Reputation: 20226
Here's the situation, I'm trying to stitch the GitHub graphql schema with an application's local schema. The application uses GitHub oAuth to connect the user to their GitHub data.
Most of the write-ups on schema stitching use an introspection query to get the remote server's schema. Unfortunately, the GitHub graphql api is authenticated with an access token. My original intent was to use the user's oAuth access token to perform the introspection but then I ran into a catch-22 wherein the introspection needs to happen at startup, i.e. before I have any authenticated users.
So the basic question is: How do I make a remote executable schema from the github graphql api?
Upvotes: 0
Views: 789
Reputation: 20226
Further reading on the subject revealed that a better pattern is to statically download the remote server's schema and then make a remote executable from it.
First you'll need to install the apollo cli:
$ npm install -g apollo
Then use it to download the GitHub schema:
$ apollo schema:download --header "Authorization: Bearer token"
--endpoint=https://api.github.com/graphql github.json
where token
is an unquoted string containing an access token to GitHub (I just used an oAuth token from my own account). As of this writing this json is 47112 lines long when prettied.
You can put this file anywhere in your app that you can import from. For example in the same directory as the code that will make a schema from it which follows here:
Code Imports:
import { HttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { makeRemoteExecutableSchema } from 'apollo-server';
import { printSchema, buildClientSchema } from 'graphql/utilities';
import fetch from 'node-fetch';
Import the actual schema
Note that you can access parts of the json file directly via object destructuring
import { __schema } from './github.json';
Build the client schema and typeDefs
Trust me, you need both of these. And yes, you're still going to use this on the server even though it says buildClient (your server is going to end up being a client of GitHub's server)
const schema = buildClientSchema({ __schema });
const typeDefs = printSchema(schema);
Setup the link
This will be used for actual queries. In this example I'm carrying the user and his/her accessToken
in the link context which will come from elsewhere.
const http = new HttpLink({ uri: 'https://api.github.com/graphql', fetch });
const link = setContext((request, previousContext) => {
const { user } = previousContext;
const { accessToken } = user;
return { headers: { Authorization: `Bearer ${accessToken}` } };
}).concat(http);
Finally, make the remote executable schema
const ghSchema = makeRemoteExecutableSchema({
schema,
typeDefs,
link,
});
export default ghSchema;
ghSchema
will be an instance of a GraphQLSchema which you can now use directly or stitch to other schemas using mergeSchemas
h/t to bessey for his comment on an Apollo feature request which finally got me to bright.
Upvotes: 2