2021-08-10 11:38:52 +02:00
|
|
|
'use strict';
|
|
|
|
|
2021-09-07 11:23:49 +02:00
|
|
|
const { isEmpty, mergeWith, isArray } = require('lodash/fp');
|
2021-08-10 11:38:52 +02:00
|
|
|
const { ApolloServer } = require('apollo-server-koa');
|
2021-08-10 17:28:53 +02:00
|
|
|
const {
|
2021-09-13 10:48:26 +02:00
|
|
|
ApolloServerPluginLandingPageDisabled,
|
|
|
|
ApolloServerPluginLandingPageGraphQLPlayground,
|
2021-08-10 17:28:53 +02:00
|
|
|
} = require('apollo-server-core');
|
2021-08-10 11:38:52 +02:00
|
|
|
const depthLimit = require('graphql-depth-limit');
|
|
|
|
const { graphqlUploadKoa } = require('graphql-upload');
|
|
|
|
|
2021-09-07 11:23:49 +02:00
|
|
|
const merge = mergeWith((a, b) => {
|
|
|
|
if (isArray(a) && isArray(b)) {
|
|
|
|
return a.concat(b);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-09-28 16:54:07 +02:00
|
|
|
module.exports = async ({ strapi }) => {
|
2021-08-10 17:28:53 +02:00
|
|
|
// Generate the GraphQL schema for the content API
|
2021-08-23 19:04:19 +02:00
|
|
|
const schema = strapi
|
|
|
|
.plugin('graphql')
|
2021-09-01 12:06:51 +02:00
|
|
|
.service('content-api')
|
|
|
|
.buildSchema();
|
2021-08-10 11:38:52 +02:00
|
|
|
|
2021-08-10 17:28:53 +02:00
|
|
|
if (isEmpty(schema)) {
|
2021-08-10 11:38:52 +02:00
|
|
|
strapi.log.warn('The GraphQL schema has not been generated because it is empty');
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-09-07 11:23:49 +02:00
|
|
|
const { config } = strapi.plugin('graphql');
|
2021-08-10 11:38:52 +02:00
|
|
|
|
2021-09-07 11:23:49 +02:00
|
|
|
const defaultServerConfig = {
|
2021-08-10 17:28:53 +02:00
|
|
|
// Schema
|
2021-08-10 11:38:52 +02:00
|
|
|
schema,
|
2021-08-10 17:28:53 +02:00
|
|
|
|
|
|
|
// Initialize loaders for this request.
|
2021-09-13 10:48:26 +02:00
|
|
|
context: ({ ctx }) => ({
|
|
|
|
state: ctx.state,
|
|
|
|
koaContext: ctx,
|
|
|
|
}),
|
2021-08-10 17:28:53 +02:00
|
|
|
|
2021-09-07 11:23:49 +02:00
|
|
|
// Validation
|
|
|
|
validationRules: [depthLimit(config('depthLimit'))],
|
2021-08-10 17:28:53 +02:00
|
|
|
|
|
|
|
// Misc
|
2021-08-10 11:38:52 +02:00
|
|
|
cors: false,
|
2021-08-10 17:28:53 +02:00
|
|
|
uploads: false,
|
2021-08-10 11:38:52 +02:00
|
|
|
bodyParserConfig: true,
|
2021-08-10 17:28:53 +02:00
|
|
|
|
|
|
|
plugins: [
|
2021-09-13 10:48:26 +02:00
|
|
|
process.env.NODE_ENV === 'production'
|
|
|
|
? ApolloServerPluginLandingPageDisabled()
|
|
|
|
: ApolloServerPluginLandingPageGraphQLPlayground(),
|
2021-08-10 17:28:53 +02:00
|
|
|
],
|
2021-08-10 11:38:52 +02:00
|
|
|
};
|
|
|
|
|
2021-09-07 11:23:49 +02:00
|
|
|
const serverConfig = merge(defaultServerConfig, config('apolloServer', {}));
|
|
|
|
|
2021-08-10 17:28:53 +02:00
|
|
|
// Create a new Apollo server
|
2021-09-07 11:23:49 +02:00
|
|
|
const server = new ApolloServer(serverConfig);
|
2021-08-10 17:28:53 +02:00
|
|
|
|
2021-09-28 11:11:03 +02:00
|
|
|
// Link the Apollo server & the Strapi app
|
|
|
|
const path = config('endpoint', '/graphql');
|
|
|
|
|
2021-08-10 17:28:53 +02:00
|
|
|
// Register the upload middleware
|
2021-09-28 11:11:03 +02:00
|
|
|
useUploadMiddleware(strapi, path);
|
2021-08-10 17:28:53 +02:00
|
|
|
|
|
|
|
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);
|
2021-08-10 11:38:52 +02:00
|
|
|
}
|
|
|
|
|
2021-09-13 10:48:26 +02:00
|
|
|
strapi.server.routes([
|
|
|
|
{
|
|
|
|
method: 'ALL',
|
2021-09-21 19:38:15 +02:00
|
|
|
path,
|
2021-09-13 10:48:26 +02:00
|
|
|
handler: [
|
|
|
|
(ctx, next) => {
|
|
|
|
ctx.state.route = {
|
|
|
|
info: {
|
|
|
|
// Indicate it's a content API route
|
|
|
|
type: 'content-api',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
return strapi.auth.authenticate(ctx, next);
|
|
|
|
},
|
|
|
|
|
|
|
|
// Apollo Server
|
2021-09-21 19:38:15 +02:00
|
|
|
server.getMiddleware({ path }),
|
2021-09-13 10:48:26 +02:00
|
|
|
],
|
|
|
|
config: {
|
|
|
|
auth: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
2021-08-10 17:28:53 +02:00
|
|
|
|
|
|
|
// Register destroy behavior
|
2021-08-24 11:01:54 +02:00
|
|
|
// 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 () => {
|
2021-08-10 17:28:53 +02:00
|
|
|
await server.stop();
|
|
|
|
};
|
|
|
|
};
|
2021-08-10 11:38:52 +02:00
|
|
|
|
2021-08-10 17:28:53 +02:00
|
|
|
/**
|
|
|
|
* Register the upload middleware powered by graphql-upload in Strapi
|
|
|
|
* @param {object} strapi
|
2021-09-28 11:11:03 +02:00
|
|
|
* @param {string} path
|
2021-08-10 17:28:53 +02:00
|
|
|
*/
|
2021-09-28 11:11:03 +02:00
|
|
|
const useUploadMiddleware = (strapi, path) => {
|
2021-08-10 11:38:52 +02:00
|
|
|
const uploadMiddleware = graphqlUploadKoa();
|
2021-08-10 17:28:53 +02:00
|
|
|
|
2021-09-09 11:31:29 +02:00
|
|
|
strapi.server.app.use((ctx, next) => {
|
2021-09-28 11:11:03 +02:00
|
|
|
if (ctx.path === path) {
|
2021-08-10 11:38:52 +02:00
|
|
|
return uploadMiddleware(ctx, next);
|
|
|
|
}
|
|
|
|
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
};
|