Skip to content

Commit

Permalink
fix(graphql): fix writing http status code
Browse files Browse the repository at this point in the history
  • Loading branch information
luas10c committed Jan 15, 2023
1 parent cdf4998 commit 951f907
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 59 deletions.
118 changes: 67 additions & 51 deletions packages/apollo/lib/drivers/apollo-base.driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ import * as omit from 'lodash.omit';
import { ApolloDriverConfig } from '../interfaces';
import { createAsyncIterator } from '../utils/async-iterator.util';

import { ApolloServer, type BaseContext } from '@apollo/server';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { expressMiddleware } from '@apollo/server/express4';
import * as express from 'express';
import * as http from 'node:http';
import * as cors from 'cors';

import fastifyApollo, {
fastifyApolloHandler,
fastifyApolloDrainPlugin,
} from '@as-integrations/fastify';

const apolloPredefinedExceptions: Partial<
Record<HttpStatus, typeof ApolloError | typeof UserInputError>
> = {
Expand All @@ -28,10 +40,10 @@ const apolloPredefinedExceptions: Partial<
export abstract class ApolloBaseDriver<
T extends Record<string, any> = ApolloDriverConfig,
> extends AbstractGraphQLDriver<T> {
protected _apolloServer: ApolloServerBase;
protected apolloServer: ApolloServerBase | ApolloServer<BaseContext>;

get instance(): ApolloServerBase {
return this._apolloServer;
get instance(): ApolloServerBase | ApolloServer<BaseContext> {
return this.apolloServer;
}

public async start(apolloOptions: T) {
Expand All @@ -48,7 +60,7 @@ export abstract class ApolloBaseDriver<
}

public stop() {
return this._apolloServer?.stop();
return this.apolloServer?.stop();
}

public async mergeDefaultOptions(options: T): Promise<T> {
Expand Down Expand Up @@ -115,68 +127,72 @@ export abstract class ApolloBaseDriver<
);
}

protected async registerExpress(
apolloOptions: T,
{ preStartHook }: { preStartHook?: () => void } = {},
) {
const { ApolloServer } = loadPackage(
'apollo-server-express',
'GraphQLModule',
() => require('apollo-server-express'),
);
const { disableHealthCheck, path, onHealthCheck, cors, bodyParserConfig } =
apolloOptions;
protected async registerExpress(options: T, hooks?: any) {
if (hooks?.preStartHook) {
hooks?.preStartHook();
}

const { path, typeDefs, resolvers, schema } = options;

const httpAdapter = this.httpAdapterHost.httpAdapter;
const app = httpAdapter.getInstance();
const httpServer = http.createServer(app);

preStartHook?.();
// Set up Apollo Server
const server = new ApolloServer({
typeDefs,
resolvers,
schema,
...options,
/**
* @TODO
* should remove serverWillStart from default plugins.
* after include plugins here
*/
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});

const apolloServer = new ApolloServer(apolloOptions as any);
await apolloServer.start();
await server.start();

apolloServer.applyMiddleware({
app,
app.use(
path,
disableHealthCheck,
onHealthCheck,
cors,
bodyParserConfig,
});
cors(options.cors),
express.json(),
expressMiddleware(server),
);

this._apolloServer = apolloServer;
this.apolloServer = server;
}

protected async registerFastify(
apolloOptions: T,
{ preStartHook }: { preStartHook?: () => void } = {},
) {
const { ApolloServer } = loadPackage(
'apollo-server-fastify',
'GraphQLModule',
() => require('apollo-server-fastify'),
);
protected async registerFastify(options: T, hooks?: any) {
if (hooks?.preStartHook) {
hooks?.preStartHook();
}

const httpAdapter = this.httpAdapterHost.httpAdapter;
const app = httpAdapter.getInstance();

preStartHook?.();
const apolloServer = new ApolloServer(apolloOptions as any);
await apolloServer.start();

const { disableHealthCheck, onHealthCheck, cors, bodyParserConfig, path } =
apolloOptions;
await app.register(
apolloServer.createHandler({
disableHealthCheck,
onHealthCheck,
cors,
bodyParserConfig,
path,
}),
);
const { path, typeDefs, resolvers, schema } = options;

const server = new ApolloServer<BaseContext>({
typeDefs,
resolvers,
schema,
plugins: [fastifyApolloDrainPlugin(app)],
});

await server.start();

app.route({
url: path,
method: ['POST', 'OPTIONS'],
handler: fastifyApolloHandler(server),
});

await app.register(fastifyApollo(server));
await app.register(cors, options.cors);

this._apolloServer = apolloServer;
this.apolloServer = server;
}

private wrapFormatErrorFn(options: T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
GraphQLExecutor,
} from 'apollo-server-core';
import { GraphQLSchema } from 'graphql';
import { CorsOptions } from 'cors';

export interface ServerRegistration {
/**
Expand All @@ -20,7 +21,7 @@ export interface ServerRegistration {
/**
* CORS configuration
*/
cors?: any | boolean;
cors?: CorsOptions;

/**
* Body-parser configuration
Expand Down
13 changes: 9 additions & 4 deletions packages/apollo/lib/utils/get-apollo-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@ import { GraphQLModule } from '@nestjs/graphql';
import { ApolloServerBase } from 'apollo-server-core';
import { ApolloDriver } from '..';

import { ApolloServer, type BaseContext } from '@apollo/server';

type GetApolloServer = (
app: INestApplicationContext,
) => ApolloServerBase | ApolloServer<BaseContext>;

/**
* Returns the underlying ApolloServer instance for a given application.
* @param app Nest application reference
* @returns Apollo Server instance used by the host application
*/
export function getApolloServer(
app: INestApplicationContext,
): ApolloServerBase {
export const getApolloServer: GetApolloServer = (app) => {
try {
const graphqlModule = app.get<GraphQLModule<ApolloDriver>>(GraphQLModule);
return graphqlModule.graphQlAdapter?.instance;
} catch (error) {}

throw new Error(
`Nest could not find the "GraphQLModule" in your application's container. Please, double-check if it's registered in the given application.`,
);
}
};
11 changes: 8 additions & 3 deletions packages/graphql/lib/interfaces/graphql-exception.interface.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { GraphQLErrorOptions } from 'graphql/error';
import type {
GraphQLErrorOptions,
GraphQLErrorExtensions,
} from 'graphql/error';

export interface ExpcetionOptions extends GraphQLErrorOptions {
http: {
status: number;
extensions: GraphQLErrorExtensions & {
http: {
status: number;
};
};
}

0 comments on commit 951f907

Please sign in to comment.