Skip to content

Instantly share code, notes, and snippets.

@josephktcheung
Last active November 19, 2021 20:31
Show Gist options
  • Save josephktcheung/fa30b4db78f052fe4f8704794826a630 to your computer and use it in GitHub Desktop.
Save josephktcheung/fa30b4db78f052fe4f8704794826a630 to your computer and use it in GitHub Desktop.
Schema stitching with subscription
import { GraphQLServer, Options } from 'graphql-yoga'
import { mergeSchemas } from 'graphql-tools';
import { getRemoteSchema } from "./remoteSchema";
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config()
}
const start = async () => {
const messageSchema = await getRemoteSchema(process.env.MESSAGE_SERVICE_GRAPHQL_URL, process.env.MESSAGE_SERVICE_SUBSCRIPTION_URL);
const userSchema = await getRemoteSchema(process.env.USER_SERVICE_GRAPHQL_URL, process.env.USER_SERVICE_SUBSCRIPTION_URL);
const schema = mergeSchemas({
schemas: [userSchema, messageSchema] as any,
});
const server = new GraphQLServer({
schema,
context: ({ connection }) => {
if (connection && connection.context) {
return connection.context;
}
}
});
const options: Options = {
port: 4000
}
server.start((options) => console.log('Server is running on http://localhost:4000'))
}
start();
import { HttpLink } from 'apollo-link-http';
import { split } from 'apollo-client-preset';
import { getMainDefinition } from 'apollo-utilities';
import * as ws from 'ws';
import { SubscriptionClient } from 'subscriptions-transport-ws/dist/client';
import fetch from 'node-fetch';
import { introspectSchema, makeRemoteExecutableSchema } from 'graphql-tools';
import { GraphQLSchema } from "graphql";
export const getRemoteSchema = async (uri: string, subUri: string): Promise<GraphQLSchema> => {
const httpLink = new HttpLink({ uri, fetch });
const wsLink = (operation, forward) => {
const context = operation.getContext();
const connectionParams = context.graphqlContext || {};
const client = new SubscriptionClient(subUri, {
connectionParams,
reconnect: true,
}, ws);
return client.request(operation);
};
const link = split(
({ query, setContext, getContext }) => {
const definition = getMainDefinition(query as any);
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription'
},
wsLink,
httpLink,
);
const schema = await introspectSchema(httpLink);
const executableSchema = makeRemoteExecutableSchema({
schema,
link,
});
return executableSchema as any;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment