125 lines
3.0 KiB
JavaScript
Raw Normal View History

'use strict';
const { isEmpty, mergeWith, isArray } = require('lodash/fp');
const { ApolloServer } = require('apollo-server-koa');
2021-08-10 17:28:53 +02:00
const {
ApolloServerPluginLandingPageDisabled,
ApolloServerPluginLandingPageGraphQLPlayground,
2021-08-10 17:28:53 +02:00
} = require('apollo-server-core');
const depthLimit = require('graphql-depth-limit');
const { graphqlUploadKoa } = require('graphql-upload');
const merge = mergeWith((a, b) => {
if (isArray(a) && isArray(b)) {
return a.concat(b);
}
});
module.exports = async ({ strapi }) => {
2021-08-10 17:28:53 +02:00
// Generate the GraphQL schema for the content API
const schema = strapi
.plugin('graphql')
.service('content-api')
.buildSchema();
2021-08-10 17:28:53 +02:00
if (isEmpty(schema)) {
strapi.log.warn('The GraphQL schema has not been generated because it is empty');
return;
}
const { config } = strapi.plugin('graphql');
const defaultServerConfig = {
2021-08-10 17:28:53 +02:00
// Schema
schema,
2021-08-10 17:28:53 +02:00
// Initialize loaders for this request.
context: ({ ctx }) => ({
state: ctx.state,
koaContext: ctx,
}),
2021-08-10 17:28:53 +02:00
// Validation
validationRules: [depthLimit(config('depthLimit'))],
2021-08-10 17:28:53 +02:00
// Misc
cors: false,
2021-08-10 17:28:53 +02:00
uploads: false,
bodyParserConfig: true,
2021-08-10 17:28:53 +02:00
plugins: [
process.env.NODE_ENV === 'production'
? ApolloServerPluginLandingPageDisabled()
: ApolloServerPluginLandingPageGraphQLPlayground(),
2021-08-10 17:28:53 +02:00
],
};
const serverConfig = merge(defaultServerConfig, config('apolloServer', {}));
2021-08-10 17:28:53 +02:00
// Create a new Apollo server
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);
}
strapi.server.routes([
{
method: 'ALL',
2021-09-21 19:38:15 +02:00
path,
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 }),
],
config: {
auth: false,
},
},
]);
2021-08-10 17:28:53 +02:00
// 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 () => {
2021-08-10 17:28:53 +02:00
await server.stop();
};
};
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) => {
const uploadMiddleware = graphqlUploadKoa();
2021-08-10 17:28:53 +02:00
strapi.server.app.use((ctx, next) => {
2021-09-28 11:11:03 +02:00
if (ctx.path === path) {
return uploadMiddleware(ctx, next);
}
return next();
});
};