Patrick Desjardins Blog
Patrick Desjardins picture from a conference

Configuring Apollo Playground and API on two different URL

Posted on: 2019-03-13

By default, Apollo GraphQL middleware install the server in Express under the same URL. If you use the URL in the browser (GET), the playground loads. If you use the URL as a POST the data is returned. The website and the API are both using the same URL. It is problematic if you want the playground to use a particular authentication system (e.g., web-based) and the API to use an other (e.g., token approach). In this article, I will present a simple way to have the web playground and the API over two different URLs.

The idea is to start two Apollo middleware and route them with different options. The playground can be even simpler that what I am presenting. I am adding a few playground settings. Because I am using TypeScript, all the fields are marked to be required, hence I am explicitly specifying the value for each. The "request.credentials" is required with the authentication mechanism under which I am developer the GraphQL.

app.use(playgroundEndpoint, authorizeUserMiddleware);
const playgroundServer = new ApolloServer({
 schema: schemas,
        engine: true,
        context: (context: GraphQLCustomResolversContext) => {
            const requestTyped = (context as any).req as IUserRequest;
            const newContext: GraphQLCustomContext = {
                loaders: new DataLoaders(requestTyped)
            };
            return newContext;
        },
        playground: {
            settings: {
                "general.betaUpdates": false,
                "editor.theme": "dark",
                "editor.reuseHeaders": true,
                "tracing.hideTracingResponse": false,
                "editor.fontSize": 14,
                "editor.fontFamily": "'Source Code Pro', 'Consolas', 'Inconsolata', 'Droid Sans Mono', 'Monaco', monospace",
                "request.credentials": "same-origin"
            }
        }
});
playgroundServer.applyMiddleware({ app, path: playgroundEndpoint, cors: true });

The second configuration is for the API. The arrangement is slightly more simple. The reason is that the middleware needs to disable the playground and nothing else.

app.use(apiEndpoint, authorizeUserMiddleware);
const apiServer = new ApolloServer({
    schema: schemas,
    context: (context: GraphQLCustomResolversContext) => {
        const requestTyped = (context as any).req as IUserRequest;
        const newContext: GraphQLCustomContext = {
            loaders: new DataLoaders(requestTyped)
        };
        return newContext;
    },
    playground: false,
    introspection: false
});
apiServer.applyMiddleware({ app, path: apiEndpoint, cors: true });

In both cases, I set a custom "authorizeUserMiddleware" that read the user credential and figure out what the user can do or not. The important parameters to disable are the playground, the introspection

The code that is hooking Apollo middleware into Express server next were you define the Express variable. From there, you need to start the server and both URLs will be served.

My Other GraphQL Blog Posts