mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 18:08:11 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			135 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| const { isEmpty, mergeWith, isArray } = require('lodash/fp');
 | |
| const { ApolloServer } = require('apollo-server-koa');
 | |
| const {
 | |
|   ApolloServerPluginLandingPageDisabled,
 | |
|   ApolloServerPluginLandingPageGraphQLPlayground,
 | |
| } = require('apollo-server-core');
 | |
| const depthLimit = require('graphql-depth-limit');
 | |
| const { graphqlUploadKoa } = require('graphql-upload');
 | |
| const formatGraphqlError = require('./format-graphql-error');
 | |
| 
 | |
| const merge = mergeWith((a, b) => {
 | |
|   if (isArray(a) && isArray(b)) {
 | |
|     return a.concat(b);
 | |
|   }
 | |
| });
 | |
| 
 | |
| /**
 | |
|  * Register the upload middleware powered by graphql-upload in Strapi
 | |
|  * @param {object} strapi
 | |
|  * @param {string} path
 | |
|  */
 | |
| const useUploadMiddleware = (strapi, path) => {
 | |
|   const uploadMiddleware = graphqlUploadKoa();
 | |
| 
 | |
|   strapi.server.app.use((ctx, next) => {
 | |
|     if (ctx.path === path) {
 | |
|       return uploadMiddleware(ctx, next);
 | |
|     }
 | |
| 
 | |
|     return next();
 | |
|   });
 | |
| };
 | |
| 
 | |
| module.exports = async ({ strapi }) => {
 | |
|   // Generate the GraphQL schema for the content API
 | |
|   const schema = strapi.plugin('graphql').service('content-api').buildSchema();
 | |
| 
 | |
|   if (isEmpty(schema)) {
 | |
|     strapi.log.warn('The GraphQL schema has not been generated because it is empty');
 | |
| 
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   const { config } = strapi.plugin('graphql');
 | |
| 
 | |
|   const path = config('endpoint');
 | |
| 
 | |
|   const defaultServerConfig = {
 | |
|     // Schema
 | |
|     schema,
 | |
| 
 | |
|     // Initialize loaders for this request.
 | |
|     context: ({ ctx }) => ({
 | |
|       state: ctx.state,
 | |
|       koaContext: ctx,
 | |
|     }),
 | |
| 
 | |
|     // Validation
 | |
|     validationRules: [depthLimit(config('depthLimit'))],
 | |
| 
 | |
|     // Errors
 | |
|     formatError: formatGraphqlError,
 | |
| 
 | |
|     // Misc
 | |
|     cors: false,
 | |
|     uploads: false,
 | |
|     bodyParserConfig: true,
 | |
| 
 | |
|     plugins: [
 | |
|       process.env.NODE_ENV === 'production' && !config('playgroundAlways')
 | |
|         ? ApolloServerPluginLandingPageDisabled()
 | |
|         : ApolloServerPluginLandingPageGraphQLPlayground(),
 | |
|     ],
 | |
| 
 | |
|     cache: 'bounded',
 | |
|   };
 | |
| 
 | |
|   const serverConfig = merge(defaultServerConfig, config('apolloServer'));
 | |
| 
 | |
|   // Create a new Apollo server
 | |
|   const server = new ApolloServer(serverConfig);
 | |
| 
 | |
|   // Register the upload middleware
 | |
|   useUploadMiddleware(strapi, path);
 | |
| 
 | |
|   try {
 | |
|     // Since Apollo-Server v3, server.start() must be called before using server.applyMiddleware()
 | |
|     await server.start();
 | |
|   } catch (e) {
 | |
|     strapi.log.error('Failed to start the Apollo server', e.message);
 | |
|   }
 | |
| 
 | |
|   // Link the Apollo server & the Strapi app
 | |
|   strapi.server.routes([
 | |
|     {
 | |
|       method: 'ALL',
 | |
|       path,
 | |
|       handler: [
 | |
|         (ctx, next) => {
 | |
|           ctx.state.route = {
 | |
|             info: {
 | |
|               // Indicate it's a content API route
 | |
|               type: 'content-api',
 | |
|             },
 | |
|           };
 | |
| 
 | |
|           // allow graphql playground to load without authentication
 | |
|           if (ctx.request.method === 'GET') return next();
 | |
| 
 | |
|           return strapi.auth.authenticate(ctx, next);
 | |
|         },
 | |
| 
 | |
|         // Apollo Server
 | |
|         server.getMiddleware({
 | |
|           path,
 | |
|           cors: serverConfig.cors,
 | |
|           bodyParserConfig: serverConfig.bodyParserConfig,
 | |
|         }),
 | |
|       ],
 | |
|       config: {
 | |
|         auth: false,
 | |
|       },
 | |
|     },
 | |
|   ]);
 | |
| 
 | |
|   // Register destroy behavior
 | |
|   // We're doing it here instead of exposing a destroy method to the strapi-server.js
 | |
|   // file since we need to have access to the ApolloServer instance
 | |
|   strapi.plugin('graphql').destroy = async () => {
 | |
|     await server.stop();
 | |
|   };
 | |
| };
 | 
