Search code examples
graphqlapollo-serverkeystonejsgraphql-schema

How can one get a complete GraphQL schema from an Apollo Server endpoint?


I'm writing a GraphQL interface between GraphQL and REST services using Apollo Server. This interface will provide a single GraphQL endpoint for an Apollo Client front.

The single service at the moment is a KeystoneJS app which provides a GraphQL endpoint, through (as far as I know) Apollo Server. To keep things simple for the moment, I'm downloading the GraphQL schema from the KeystoneJS server GraphQL Playground and using it as my interface's GraphQL schema (after removing definitions that Keystone generates and Apollo Server doesn't understand).

I'd like to automate this process -- that is, somehow 'grab' the GraphQL schema that KeystoneJS/Apollo Server generates, just as if I were to download it from the GraphQL Playground. Is there a way to do this from the endpoint? (I don't want to touch the KeystoneJS internals, just access the schema through the endpoint)


Solution

  • You can run an introspection query against any GraphQL service (assuming they haven't disabled introspection -- some services do that in production). The result of this query can be passed to buildClientSchema to reconstruct the schema from the introspection result (without any of the field resolution logic, naturally). You can then convert the returned GraphQLSchema object into SDL by calling printSchema.

    Here's an example using axios, but you can use any http library you like to make the request:

    const { buildClientSchema, getIntrospectionQuery, printSchema } = require('graphql')
    const axios = require('axios')
    
    const ENDPOINT_URL = "";
    
    (async () => {
        const res = await axios.post(ENDPOINT_URL, { query: getIntrospectionQuery() })
        const schema = buildClientSchema(res.data.data)
        const sdl = printSchema(schema)
        console.log(sdl)
    })()
    
    

    Note: the first "data" is what the axios API calls the actual JSON response from the server, while the second "data" is the actual "data" property, which is what we want to pass to buildClientSchema.