Skip to content

Commit

Permalink
Upgrade example Apollo Server implementation to Apollo Server 4 (arda…
Browse files Browse the repository at this point in the history
  • Loading branch information
casey-chow authored Feb 10, 2023
1 parent d90d361 commit 86c026f
Show file tree
Hide file tree
Showing 3 changed files with 473 additions and 131 deletions.
73 changes: 52 additions & 21 deletions examples/apollo-server/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
/* eslint-disable no-console */
import { ApolloServer } from 'apollo-server';
import { envelop, useSchema } from '@envelop/core';
import { ApolloServer } from '@apollo/server';
import { envelop, useEngine, useSchema } from '@envelop/core';
import { parse, validate, subscribe, execute } from 'graphql';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { ApolloServerPluginLandingPageGraphQLPlayground } from 'apollo-server-core';
import { startStandaloneServer } from '@apollo/server/standalone';
import { ApolloServerPluginLandingPageGraphQLPlayground } from '@apollo/server-plugin-landing-page-graphql-playground';
import {
GatewayApolloConfig,
GatewayExecutor,
GatewayInterface,
GatewayLoadResult,
GatewaySchemaLoadOrUpdateCallback,
GatewayUnsubscriber,
} from '@apollo/server-gateway-interface';

const schema = makeExecutableSchema({
typeDefs: /* GraphQL */ `
Expand All @@ -19,27 +28,49 @@ const schema = makeExecutableSchema({
});

const getEnveloped = envelop({
parse,
validate,
subscribe,
execute,
plugins: [useSchema(schema)],
plugins: [useEngine({ parse, validate, subscribe, execute }), useSchema(schema)],
});

const executor: GatewayExecutor = async requestContext => {
const { schema, execute, contextFactory } = getEnveloped({ req: requestContext.request.http });

return execute({
schema,
document: requestContext.document,
contextValue: await contextFactory(),
variableValues: requestContext.request.variables,
operationName: requestContext.operationName,
});
};

// Apollo Server 4 requires a custom gateway to enable custom executors:
// https://www.apollographql.com/docs/apollo-server/migration/#executor
class Gateway implements GatewayInterface {
private schemaCallback?: GatewaySchemaLoadOrUpdateCallback;

async load(options: { apollo: GatewayApolloConfig }): Promise<GatewayLoadResult> {
// Apollo expects this schema to be called before this function resolves:
// https://github.com/apollographql/apollo-server/issues/7340#issuecomment-1407071706
this.schemaCallback?.({ apiSchema: schema, coreSupergraphSdl: '' });

return { executor };
}

onSchemaLoadOrUpdate(callback: GatewaySchemaLoadOrUpdateCallback): GatewayUnsubscriber {
this.schemaCallback = callback;
return () => {};
}

async stop() {}
}

const server = new ApolloServer({
schema,
executor: async requestContext => {
const { schema, execute, contextFactory } = getEnveloped({ req: requestContext.request.http });

return execute({
schema,
document: requestContext.document,
contextValue: await contextFactory(),
variableValues: requestContext.request.variables,
operationName: requestContext.operationName,
});
},
gateway: new Gateway(),
plugins: [ApolloServerPluginLandingPageGraphQLPlayground({ endpoint: '/graphql' })],
});

server.listen(3000);
(async () => {
await startStandaloneServer(server, {
listen: { port: 3000 },
});
})();
6 changes: 3 additions & 3 deletions examples/apollo-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
"author": "Dotan Simha",
"license": "MIT",
"dependencies": {
"@apollo/server": "^4.3.2",
"@apollo/server-plugin-landing-page-graphql-playground": "^4.0.0",
"@envelop/core": "*",
"apollo-server": "3.5.0",
"apollo-server-core": "3.5.0",
"@graphql-tools/schema": "8.5.0",
"graphql": "16.6.0"
},
"devDependencies": {
"@types/node": "15.6.1",
"ts-node": "10.0.0",
"ts-node": "10.6.0",
"typescript": "4.8.4"
},
"scripts": {
Expand Down
Loading

0 comments on commit 86c026f

Please sign in to comment.