feat: Switch GraphQL server from Yoga v2 to Apollo v4 (#8959)
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import corsMiddleware from 'cors';
|
||||
import { createServer, renderGraphiQL } from '@graphql-yoga/node';
|
||||
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js';
|
||||
import { ApolloServer } from '@apollo/server';
|
||||
import { expressMiddleware } from '@apollo/server/express4';
|
||||
import { ApolloServerPluginCacheControlDisabled } from '@apollo/server/plugin/disabled';
|
||||
import express from 'express';
|
||||
import { execute, subscribe } from 'graphql';
|
||||
import { SubscriptionServer } from 'subscriptions-transport-ws';
|
||||
import { handleParseErrors, handleParseHeaders, handleParseSession } from '../middlewares';
|
||||
@@ -33,16 +37,13 @@ class ParseGraphQLServer {
|
||||
try {
|
||||
return {
|
||||
schema: await this.parseGraphQLSchema.load(),
|
||||
context: ({ req: { info, config, auth } }) => ({
|
||||
info,
|
||||
config,
|
||||
auth,
|
||||
}),
|
||||
maskedErrors: false,
|
||||
multipart: {
|
||||
fileSize: this._transformMaxUploadSizeToBytes(
|
||||
this.parseServer.config.maxUploadSize || '20mb'
|
||||
),
|
||||
context: async ({ req, res }) => {
|
||||
res.set('access-control-allow-origin', req.get('origin') || '*');
|
||||
return {
|
||||
info: req.info,
|
||||
config: req.config,
|
||||
auth: req.auth,
|
||||
};
|
||||
},
|
||||
};
|
||||
} catch (e) {
|
||||
@@ -57,8 +58,21 @@ class ParseGraphQLServer {
|
||||
if (schemaRef === newSchemaRef && this._server) {
|
||||
return this._server;
|
||||
}
|
||||
const options = await this._getGraphQLOptions();
|
||||
this._server = createServer(options);
|
||||
const { schema, context } = await this._getGraphQLOptions();
|
||||
const apollo = new ApolloServer({
|
||||
csrfPrevention: {
|
||||
// See https://www.apollographql.com/docs/router/configuration/csrf/
|
||||
// needed since we use graphql upload
|
||||
requestHeaders: ['X-Parse-Application-Id'],
|
||||
},
|
||||
introspection: true,
|
||||
plugins: [ApolloServerPluginCacheControlDisabled()],
|
||||
schema,
|
||||
});
|
||||
await apollo.start();
|
||||
this._server = expressMiddleware(apollo, {
|
||||
context,
|
||||
});
|
||||
return this._server;
|
||||
}
|
||||
|
||||
@@ -79,14 +93,21 @@ class ParseGraphQLServer {
|
||||
if (!app || !app.use) {
|
||||
requiredParameter('You must provide an Express.js app instance!');
|
||||
}
|
||||
|
||||
app.use(this.config.graphQLPath, corsMiddleware());
|
||||
app.use(this.config.graphQLPath, handleParseHeaders);
|
||||
app.use(this.config.graphQLPath, handleParseSession);
|
||||
app.use(this.config.graphQLPath, handleParseErrors);
|
||||
app.use(this.config.graphQLPath, async (req, res) => {
|
||||
app.use(
|
||||
this.config.graphQLPath,
|
||||
graphqlUploadExpress({
|
||||
maxFileSize: this._transformMaxUploadSizeToBytes(
|
||||
this.parseServer.config.maxUploadSize || '20mb'
|
||||
),
|
||||
})
|
||||
);
|
||||
app.use(this.config.graphQLPath, express.json(), async (req, res, next) => {
|
||||
const server = await this._getServer();
|
||||
return server(req, res);
|
||||
return server(req, res, next);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -94,20 +115,33 @@ class ParseGraphQLServer {
|
||||
if (!app || !app.get) {
|
||||
requiredParameter('You must provide an Express.js app instance!');
|
||||
}
|
||||
|
||||
app.get(
|
||||
this.config.playgroundPath ||
|
||||
requiredParameter('You must provide a config.playgroundPath to applyPlayground!'),
|
||||
(_req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.write(
|
||||
renderGraphiQL({
|
||||
endpoint: this.config.graphQLPath,
|
||||
subscriptionEndpoint: this.config.subscriptionsPath,
|
||||
headers: JSON.stringify({
|
||||
'X-Parse-Application-Id': this.parseServer.config.appId,
|
||||
'X-Parse-Master-Key': this.parseServer.config.masterKey,
|
||||
}),
|
||||
})
|
||||
`<div id="sandbox" style="position:absolute;top:0;right:0;bottom:0;left:0"></div>
|
||||
<script src="https://embeddable-sandbox.cdn.apollographql.com/_latest/embeddable-sandbox.umd.production.min.js"></script>
|
||||
<script>
|
||||
new window.EmbeddedSandbox({
|
||||
target: "#sandbox",
|
||||
endpointIsEditable: false,
|
||||
initialEndpoint: "${JSON.stringify(this.config.graphQLPath)}",
|
||||
handleRequest: (endpointUrl, options) => {
|
||||
return fetch(endpointUrl, {
|
||||
...options,
|
||||
headers: {
|
||||
...options.headers,
|
||||
'X-Parse-Application-Id': "${JSON.stringify(this.parseServer.config.appId)}",
|
||||
'X-Parse-Master-Key': "${JSON.stringify(this.parseServer.config.masterKey)}",
|
||||
},
|
||||
})
|
||||
},
|
||||
});
|
||||
// advanced options: https://www.apollographql.com/docs/studio/explorer/sandbox#embedding-sandbox
|
||||
</script>`
|
||||
);
|
||||
res.end();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user