mirror of
https://github.com/vale981/apollo-server
synced 2025-03-06 10:11:40 -05:00
apollo-server-hapi: initial implementation of apollo-server base class
This commit is contained in:
parent
9fa4a8a62b
commit
98ca26a303
4 changed files with 114 additions and 6 deletions
|
@ -25,12 +25,16 @@
|
|||
},
|
||||
"homepage": "https://github.com/apollographql/apollo-server#readme",
|
||||
"dependencies": {
|
||||
"apollo-server-core": "^1.3.6",
|
||||
"accept": "^3.0.2",
|
||||
"apollo-server-core": "2.0.0-beta.0",
|
||||
"apollo-server-module-graphiql": "^1.3.4",
|
||||
"boom": "^7.1.0"
|
||||
"boom": "^7.1.0",
|
||||
"graphql-playground-html": "^1.5.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/graphql": "0.12.7",
|
||||
"@types/hapi": "^17.0.12",
|
||||
"@types/node": "^10.0.6",
|
||||
"apollo-server-integration-testsuite": "^1.3.6",
|
||||
"hapi": "17.4.0"
|
||||
},
|
||||
|
|
86
packages/apollo-server-hapi/src/ApolloServer.ts
Normal file
86
packages/apollo-server-hapi/src/ApolloServer.ts
Normal file
|
@ -0,0 +1,86 @@
|
|||
import * as hapi from 'hapi';
|
||||
import { createServer, Server as HttpServer } from 'http';
|
||||
import { ApolloServerBase, EngineLauncherOptions } from 'apollo-server-core';
|
||||
import { parseAll } from 'accept';
|
||||
import { renderPlaygroundPage } from 'graphql-playground-html';
|
||||
|
||||
import { graphqlHapi } from './hapiApollo';
|
||||
|
||||
export interface ServerRegistration {
|
||||
app: hapi.Server;
|
||||
server: ApolloServerBase<hapi.Request>;
|
||||
path?: string;
|
||||
subscriptions?: boolean;
|
||||
}
|
||||
|
||||
export interface HapiListenOptions {
|
||||
port?: number | string;
|
||||
host?: string; // default: ''. This is where engineproxy listens.
|
||||
pipePath?: string;
|
||||
graphqlPaths?: string[]; // default: ['/graphql']
|
||||
innerHost?: string; // default: '127.0.0.1'. This is where Node listens.
|
||||
launcherOptions?: EngineLauncherOptions;
|
||||
}
|
||||
|
||||
export const registerServer = async ({
|
||||
app,
|
||||
server,
|
||||
path,
|
||||
}: ServerRegistration) => {
|
||||
if (!path) path = '/graphql';
|
||||
|
||||
await app.ext({
|
||||
type: 'onRequest',
|
||||
method: function(request, h) {
|
||||
if (request.path !== path) {
|
||||
return h.continue;
|
||||
}
|
||||
if (!server.disableTools && request.method === 'get') {
|
||||
//perform more expensive content-type check only if necessary
|
||||
const accept = parseAll(request.app);
|
||||
const types = accept.mediaTypes as string[];
|
||||
const prefersHTML =
|
||||
types.find(
|
||||
(x: string) => x === 'text/html' || x === 'application/json',
|
||||
) === 'text/html';
|
||||
|
||||
if (prefersHTML) {
|
||||
return h
|
||||
.response(
|
||||
renderPlaygroundPage({
|
||||
subscriptionsEndpoint: server.subscriptions && path,
|
||||
endpoint: path,
|
||||
version: '',
|
||||
}),
|
||||
)
|
||||
.type('text/html');
|
||||
}
|
||||
}
|
||||
return h.continue;
|
||||
},
|
||||
});
|
||||
|
||||
await app.register({
|
||||
plugin: graphqlHapi,
|
||||
options: {
|
||||
path: path,
|
||||
graphqlOptions: server.request.bind(server),
|
||||
route: {
|
||||
cors: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
server.use({ path, getHttp: () => app.listener });
|
||||
|
||||
const listen = server.listen;
|
||||
server.listen = async options => {
|
||||
//requires that autoListen is false, so that
|
||||
//hapi sets up app.listener without start
|
||||
await app.start();
|
||||
|
||||
//starts the hapi listener at a random port when engine proxy used,
|
||||
//otherwise will start the server at the provided port
|
||||
return listen({ ...options });
|
||||
};
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
import * as Boom from 'boom';
|
||||
import { Server, Response, Request, ReplyNoContinue } from 'hapi';
|
||||
import { Server, Request } from 'hapi';
|
||||
import * as GraphiQL from 'apollo-server-module-graphiql';
|
||||
import {
|
||||
GraphQLOptions,
|
||||
|
@ -39,13 +39,17 @@ const graphqlHapi: IPlugin = {
|
|||
method: ['GET', 'POST'],
|
||||
path: options.path || '/graphql',
|
||||
vhost: options.vhost || undefined,
|
||||
config: options.route || {},
|
||||
options: options.route || {},
|
||||
handler: async (request, h) => {
|
||||
try {
|
||||
const gqlResponse = await runHttpQuery([request], {
|
||||
method: request.method.toUpperCase(),
|
||||
options: options.graphqlOptions,
|
||||
query: request.method === 'post' ? request.payload : request.query,
|
||||
query:
|
||||
request.method === 'post'
|
||||
? //TODO type payload as string or Record
|
||||
(request.payload as any)
|
||||
: request.query,
|
||||
});
|
||||
|
||||
const response = h.response(gqlResponse);
|
||||
|
@ -98,7 +102,7 @@ const graphiqlHapi: IPlugin = {
|
|||
server.route({
|
||||
method: 'GET',
|
||||
path: options.path || '/graphiql',
|
||||
config: options.route || {},
|
||||
options: options.route || {},
|
||||
handler: async (request, h) => {
|
||||
const graphiqlString = await GraphiQL.resolveGraphiQLString(
|
||||
request.query,
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
// Expose types which can be used by both middleware flavors.
|
||||
export { GraphQLOptions } from 'apollo-server-core';
|
||||
export {
|
||||
ApolloError,
|
||||
toApolloError,
|
||||
SyntaxError,
|
||||
ValidationError,
|
||||
AuthenticationError,
|
||||
ForbiddenError,
|
||||
} from 'apollo-server-core';
|
||||
|
||||
export {
|
||||
IRegister,
|
||||
HapiOptionsFunction,
|
||||
|
@ -7,3 +18,6 @@ export {
|
|||
graphqlHapi,
|
||||
graphiqlHapi,
|
||||
} from './hapiApollo';
|
||||
|
||||
// ApolloServer integration
|
||||
export { registerServer } from './ApolloServer';
|
||||
|
|
Loading…
Add table
Reference in a new issue