Skip to content

Commit

Permalink
core, integrations: break apart coupling of introspection and gui enable
Browse files Browse the repository at this point in the history
  • Loading branch information
evans committed Jun 13, 2018
1 parent db8eba8 commit 5770674
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 10 deletions.
16 changes: 9 additions & 7 deletions packages/apollo-server-core/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,17 @@ export class ApolloServerBase {
const env = process.env.NODE_ENV;
const isDev = env !== 'production' && env !== 'test';

// 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 { introspection: true }
// to the constructor of ApolloServer
// we use this.disableTools to track this internally for later use when
// constructing middleware by frameworks
if (typeof introspection === 'boolean') this.disableTools = !introspection;
else this.disableTools = !isDev;
// constructing middleware by frameworks to disable graphql playground
this.disableTools = !isDev;

if (this.disableTools) {
// if this is local dev, introspection should turned on
// in production, we can manually turn introspection on by passing {
// introspection: true } to the constructor of ApolloServer
if (
(typeof introspection === 'boolean' && !introspection) ||
(introspection === undefined && !isDev)
) {
const noIntro = [NoIntrospection];
requestOptions.validationRules = requestOptions.validationRules
? requestOptions.validationRules.concat(noIntro)
Expand Down
57 changes: 56 additions & 1 deletion packages/apollo-server-express/src/ApolloServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,60 @@ describe('apollo-server-express', () => {
expect(result.errors, 'errors should exist').not.to.exist;
});

it('can enable gui separately from instrospection during production', async () => {
const INTROSPECTION_QUERY = `
{
__schema {
directives {
name
}
}
}
`;
const nodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = 'production';

server = new ApolloServer({
typeDefs,
resolvers,
});
app = express();

registerServer({ app, server, enableGUI: true });

const { url } = await server.listen();
const apolloFetch = createApolloFetch({ uri: url });
const result = await apolloFetch({ query: INTROSPECTION_QUERY });

expect(result.errors.length).to.equal(1);
expect(result.errors[0].extensions.code).to.equal(
'GRAPHQL_VALIDATION_FAILED',
);

return new Promise((resolve, reject) => {
request(
{
url,
method: 'GET',
headers: {
accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
},
},
(error, response, body) => {
process.env.NODE_ENV = nodeEnv;
if (error) {
reject(error);
} else {
expect(body).to.contain('GraphQLPlayground');
expect(response.statusCode).to.equal(200);
resolve();
}
},
);
});
});

it('renders GraphQL playground when browser requests', async () => {
const nodeEnv = process.env.NODE_ENV;
delete process.env.NODE_ENV;
Expand Down Expand Up @@ -172,6 +226,7 @@ describe('apollo-server-express', () => {
registerServer({ app, server, bodyParserConfig: { limit: 0 } });

const { port } = await server.listen();

return new Promise((resolve, reject) => {
request(
{
Expand Down Expand Up @@ -260,7 +315,7 @@ describe('apollo-server-express', () => {
});
});
describe('file uploads', () => {
xit('enabled uploads', async () => {
it('enabled uploads', async () => {
server = new ApolloServer({
typeDefs: gql`
type File {
Expand Down
8 changes: 7 additions & 1 deletion packages/apollo-server-express/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export interface ServerRegistration {
bodyParserConfig?: OptionsJson;
onHealthCheck?: (req: express.Request) => Promise<any>;
disableHealthCheck?: boolean;
enableGUI?: boolean;
//https://github.com/jaydenseric/apollo-upload-server#options
uploads?: boolean | Record<string, any>;
}
Expand Down Expand Up @@ -79,6 +80,7 @@ export const registerServer = async ({
cors,
bodyParserConfig,
disableHealthCheck,
enableGUI,
onHealthCheck,
uploads,
}: ServerRegistration) => {
Expand Down Expand Up @@ -132,7 +134,11 @@ export const registerServer = async ({
uploadsMiddleware ? uploadsMiddleware : (_req, _res, next) => next(),
(req, res, next) => {
// make sure we check to see if graphql gui should be on
if (!server.disableTools && req.method === 'GET') {
// enableGUI takes precedence over the server tools setting
if (
(enableGUI || (enableGUI === undefined && !server.disableTools)) &&
req.method === 'GET'
) {
//perform more expensive content-type check only if necessary
const accept = accepts(req);
const types = accept.types() as string[];
Expand Down
8 changes: 7 additions & 1 deletion packages/apollo-server-hapi/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface ServerRegistration {
cors?: boolean;
onHealthCheck?: (request: hapi.Request) => Promise<any>;
disableHealthCheck?: boolean;
enableGUI?: boolean;
uploads?: boolean | Record<string, any>;
}

Expand Down Expand Up @@ -65,6 +66,7 @@ export const registerServer = async ({
cors,
path,
disableHealthCheck,
enableGUI,
onHealthCheck,
uploads,
}: ServerRegistration) => {
Expand Down Expand Up @@ -118,7 +120,11 @@ server.listen({ http: { port: YOUR_PORT_HERE } });
);
}

if (!server.disableTools && request.method === 'get') {
// enableGUI takes precedence over the server tools setting
if (
(enableGUI || (enableGUI === undefined && !server.disableTools)) &&
request.method === 'get'
) {
//perform more expensive content-type check only if necessary
const accept = parseAll(request.headers);
const types = accept.mediaTypes as string[];
Expand Down

0 comments on commit 5770674

Please sign in to comment.