graphiql > gui and make content-type check only if necessary

This commit is contained in:
Evans Hauser 2018-04-25 13:40:20 -07:00
parent 68a368b775
commit 0a770964be
No known key found for this signature in database
GPG key ID: 88AF586817F52EEC
4 changed files with 35 additions and 33 deletions

View file

@ -3,7 +3,7 @@ import * as cors from 'cors';
import { json } from 'body-parser'; import { json } from 'body-parser';
import { createServer, Server as HttpServer } from 'http'; import { createServer, Server as HttpServer } from 'http';
import { graphqlExpress } from 'apollo-server-express'; import { graphqlExpress } from 'apollo-server-express';
import graphiql from 'graphql-playground-middleware-express'; import gui from 'graphql-playground-middleware-express';
import * as accepts from 'accepts'; import * as accepts from 'accepts';
import { ApolloServerBase } from './utils/ApolloServer'; import { ApolloServerBase } from './utils/ApolloServer';
@ -22,21 +22,21 @@ export class ApolloServer extends ApolloServerBase<
const path = config.path || '/graphql'; const path = config.path || '/graphql';
app.use(path, cors(config.cors), json(), (req, res, next) => { app.use(path, cors(config.cors), json(), (req, res, next) => {
// only show graphiql if we want html for a GET if (config.gui !== false && req.method === 'GET') {
const accept = accepts(req); //perform more expensive content-type check only if necessary
const types = accept.types() as string[]; const accept = accepts(req);
const isHTML = const types = accept.types() as string[];
types.find( const prefersHTML =
(x: string) => x === 'text/html' || x === 'application/json', types.find(
) === 'text/html'; (x: string) => x === 'text/html' || x === 'application/json',
) === 'text/html';
// make sure we check to see if graphiql should be on if (prefersHTML) {
// change opts.graphiql type to be boolean return gui({
if (config.graphiql !== false && req.method === 'GET' && isHTML) { endpoint: path,
return graphiql({ subscriptionsEndpoint: config.subscriptions && path,
endpoint: path, })(req, res, next);
subscriptionsEndpoint: config.subscriptions && path, }
})(req, res, next);
} }
return graphqlExpress(request)(req, res, next); return graphqlExpress(request)(req, res, next);
}); });

View file

@ -6,7 +6,7 @@ import * as accepts from 'accepts';
import { createServer, Server as HttpServer } from 'http'; import { createServer, Server as HttpServer } from 'http';
import { graphqlKoa } from 'apollo-server-koa'; import { graphqlKoa } from 'apollo-server-koa';
import graphiql from 'graphql-playground-middleware-koa'; import gui from 'graphql-playground-middleware-koa';
import { ApolloServerBase } from './utils/ApolloServer'; import { ApolloServerBase } from './utils/ApolloServer';
import { MiddlewareRegistrationOptions } from './utils/types'; import { MiddlewareRegistrationOptions } from './utils/types';
@ -28,20 +28,22 @@ export class ApolloServer extends ApolloServerBase<
router.use(path, cors(config.cors)); router.use(path, cors(config.cors));
router.use(path, koaBody()); router.use(path, koaBody());
router.all(path, async (ctx, next) => { router.all(path, async (ctx, next) => {
const accept = accepts(ctx.req); // make sure we check to see if graphql gui should be on
const types = accept.types() as string[]; if (config.gui !== false && ctx.req.method === 'GET') {
const isHTML = //perform more expensive content-type check only if necessary
types.find( const accept = accepts(ctx.req);
(x: string) => x === 'text/html' || x === 'application/json', const types = accept.types() as string[];
) === 'text/html'; const prefersHTML =
types.find(
(x: string) => x === 'text/html' || x === 'application/json',
) === 'text/html';
// make sure we check to see if graphiql should be on if (prefersHTML) {
// change opts.graphiql type to be boolean return gui({
if (config.graphiql !== false && ctx.req.method === 'GET' && isHTML) { endpoint: path,
return graphiql({ subscriptionsEndpoint: config.subscriptions && path,
endpoint: path, })(ctx, next);
subscriptionsEndpoint: config.subscriptions && path, }
})(ctx, next);
} }
return graphqlKoa(request)(ctx, next); return graphqlKoa(request)(ctx, next);
}); });

View file

@ -92,7 +92,7 @@ export class ApolloServerBase<
...requestOptions ...requestOptions
} = config; } = config;
// if this is local dev, we want graphiql and introspection to be turned on // if this is local dev, we want graphql gui and introspection to be turned on
// in production, you can manually turn these on by passing { enableIntrospection: true } // in production, you can manually turn these on by passing { enableIntrospection: true }
// to the constructor of ApolloServer // to the constructor of ApolloServer
// we use this.disableTools to track this internally for later use when // we use this.disableTools to track this internally for later use when
@ -186,7 +186,7 @@ export class ApolloServerBase<
cors: this.cors, cors: this.cors,
subscriptions: true, subscriptions: true,
...opts, ...opts,
graphiql: opts.graphiql && !this.disableTools, gui: opts.gui && !this.disableTools,
app: this.app, app: this.app,
request: this.request.bind(this), request: this.request.bind(this),
}; };

View file

@ -76,7 +76,7 @@ export interface ListenOptions {
export interface MiddlewareOptions { export interface MiddlewareOptions {
path?: string; path?: string;
graphiql?: boolean; gui?: boolean;
subscriptions?: boolean; subscriptions?: boolean;
} }
@ -86,7 +86,7 @@ export interface MiddlewareRegistrationOptions<
Cors = CorsOptions Cors = CorsOptions
> { > {
path?: string; path?: string;
graphiql?: boolean; gui?: boolean;
subscriptions?: boolean; subscriptions?: boolean;
cors?: Cors; cors?: Cors;
app: Server; app: Server;