mirror of
https://github.com/vale981/apollo-server
synced 2025-03-04 17:21:42 -05:00
Core refactor hapi (#36)
* Revert "get supertest working for TS"
This reverts commit 300b32fa5a
.
* initial hapi plugin
* working hapi server
* update exports for es6 support
This commit is contained in:
parent
300b32fa5a
commit
f6f25c611e
8 changed files with 90 additions and 46 deletions
|
@ -41,6 +41,7 @@
|
|||
"es6-promise": "^3.2.1",
|
||||
"express": "^4.13.4",
|
||||
"graphql": "^0.6.0",
|
||||
"hapi": "^13.4.1",
|
||||
"source-map-support": "^0.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -7,58 +7,51 @@ import {
|
|||
execute,
|
||||
} from 'graphql';
|
||||
|
||||
import { Promise } from 'es6-promise';
|
||||
|
||||
export interface GqlResponse {
|
||||
data?: Object;
|
||||
errors?: Array<string>;
|
||||
}
|
||||
|
||||
function runQuery({
|
||||
schema,
|
||||
query,
|
||||
rootValue,
|
||||
context,
|
||||
variables,
|
||||
operationName,
|
||||
}: {
|
||||
schema: GraphQLSchema,
|
||||
query: string | Document,
|
||||
rootValue?: any,
|
||||
context?: any,
|
||||
variables?: { [key: string]: any },
|
||||
operationName?: string,
|
||||
//logFunction?: function => void
|
||||
//validationRules?: No, too risky. If you want extra validation rules, then parse it yourself.
|
||||
}): Promise<GraphQLResult> {
|
||||
export interface QueryOptions {
|
||||
schema: GraphQLSchema;
|
||||
query: string | Document;
|
||||
rootValue?: any;
|
||||
context?: any;
|
||||
variables?: { [key: string]: any };
|
||||
operationName?: string;
|
||||
//logFunction?: function => void
|
||||
//validationRules?: No, too risky. If you want extra validation rules, then parse it yourself.
|
||||
}
|
||||
|
||||
function runQuery(options: QueryOptions): Promise<GraphQLResult> {
|
||||
let documentAST: Document;
|
||||
|
||||
// if query is already an AST, don't parse or validate
|
||||
if (typeof query === 'string') {
|
||||
if (typeof options.query === 'string') {
|
||||
// parse
|
||||
try {
|
||||
documentAST = parse(query);
|
||||
documentAST = parse(options.query as string);
|
||||
} catch (syntaxError) {
|
||||
return Promise.resolve({ errors: [syntaxError] });
|
||||
}
|
||||
|
||||
// validate
|
||||
const validationErrors = validate(schema, documentAST);
|
||||
const validationErrors = validate(options.schema, documentAST);
|
||||
if (validationErrors.length) {
|
||||
return Promise.resolve({ errors: validationErrors });
|
||||
}
|
||||
} else {
|
||||
documentAST = query;
|
||||
documentAST = options.query as Document;
|
||||
}
|
||||
|
||||
// execute
|
||||
return execute(
|
||||
schema,
|
||||
options.schema,
|
||||
documentAST,
|
||||
rootValue,
|
||||
context,
|
||||
variables,
|
||||
operationName
|
||||
options.rootValue,
|
||||
options.context,
|
||||
options.variables,
|
||||
options.operationName
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
import expressApollo from './integrations/expressApollo';
|
||||
|
||||
export { expressApollo };
|
||||
export { graphqlHTTP } from './integrations/expressApollo';
|
||||
export { HapiApollo } from './integrations/hapiApollo';
|
||||
|
|
|
@ -11,7 +11,8 @@ import {
|
|||
|
||||
// TODO use import, not require... help appreciated.
|
||||
import * as express from 'express';
|
||||
import request from 'supertest-as-promised';
|
||||
// tslint:disable-next-line
|
||||
const request = require('supertest-as-promised');
|
||||
|
||||
import { graphqlHTTP, ExpressApolloOptions, renderGraphiQL } from './expressApollo';
|
||||
|
||||
|
@ -52,9 +53,7 @@ describe('expressApollo', () => {
|
|||
};
|
||||
return request(app).get(
|
||||
'/graphql?query={ testString }'
|
||||
)
|
||||
.expect(200)
|
||||
.then((res) => {
|
||||
).then((res) => {
|
||||
return expect(res.body.data).to.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@ import * as express from 'express';
|
|||
import * as graphql from 'graphql';
|
||||
import { runQuery } from '../core/runQuery';
|
||||
|
||||
import { renderGraphiQL, GraphiQLData } from '../modules/renderGraphiQL';
|
||||
import * as GraphiQL from '../modules/renderGraphiQL';
|
||||
|
||||
// TODO: will these be the same or different for other integrations?
|
||||
export interface ExpressApolloOptions {
|
||||
|
@ -15,7 +15,11 @@ export interface ExpressApolloOptions {
|
|||
// answer: yes, it does. Func(req) => options
|
||||
}
|
||||
|
||||
export function graphqlHTTP(options: ExpressApolloOptions) {
|
||||
export interface ExpressHandler {
|
||||
(req: express.Request, res: express.Response, next): void;
|
||||
}
|
||||
|
||||
export function graphqlHTTP(options: ExpressApolloOptions): ExpressHandler {
|
||||
if (!options) {
|
||||
throw new Error('Apollo graphqlHTTP middleware requires options.');
|
||||
}
|
||||
|
@ -46,9 +50,9 @@ function getQueryString(req: express.Request): string {
|
|||
|
||||
// this returns the html for the GraphiQL interactive query UI
|
||||
// TODO: it's still missing a way to tell it where the GraphQL endpoint is.
|
||||
export function renderGraphiQL(options: GraphiQLData) {
|
||||
export function renderGraphiQL(options: GraphiQL.GraphiQLData) {
|
||||
return (req: express.Request, res: express.Response, next) => {
|
||||
const graphiQLString = renderGraphiQL({
|
||||
const graphiQLString = GraphiQL.renderGraphiQL({
|
||||
query: options.query,
|
||||
variables: options.variables,
|
||||
operationName: options.operationName,
|
||||
|
|
52
src/integrations/hapiApollo.ts
Normal file
52
src/integrations/hapiApollo.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import * as hapi from 'hapi';
|
||||
import * as graphql from 'graphql';
|
||||
import { runQuery } from '../core/runQuery';
|
||||
|
||||
|
||||
export interface IRegister {
|
||||
(server: hapi.Server, options: any, next: any): void;
|
||||
attributes?: any;
|
||||
}
|
||||
|
||||
export interface HapiApolloOptions {
|
||||
schema: graphql.GraphQLSchema;
|
||||
formatError?: Function;
|
||||
rootValue?: any;
|
||||
context?: any;
|
||||
logFunction?: Function;
|
||||
}
|
||||
|
||||
export class HapiApollo {
|
||||
constructor() {
|
||||
this.register.attributes = {
|
||||
name: 'graphql',
|
||||
version: '0.0.1',
|
||||
};
|
||||
}
|
||||
|
||||
public register: IRegister = (server: hapi.Server, options: HapiApolloOptions, next) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/test',
|
||||
handler: (request, reply) => {
|
||||
reply('test passed');
|
||||
},
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
handler: (request, reply) => {
|
||||
return runQuery({
|
||||
schema: options.schema,
|
||||
query: request.payload,
|
||||
}).then(gqlResponse => {
|
||||
reply({ data: gqlResponse.data });
|
||||
}).catch(errors => {
|
||||
reply({ errors: errors }).code(500);
|
||||
});
|
||||
},
|
||||
});
|
||||
next();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
|
|
|
@ -4,18 +4,14 @@
|
|||
"graphql": "github:nitintutlani/typed-graphql"
|
||||
},
|
||||
"globalDependencies": {
|
||||
"bluebird": "registry:dt/bluebird#2.0.0+20160319051630",
|
||||
"body-parser": "registry:dt/body-parser#0.0.0+20160317120654",
|
||||
"es6-promise": "registry:dt/es6-promise#0.0.0+20160317120654",
|
||||
"express": "registry:dt/express#4.0.0+20160317120654",
|
||||
"express-serve-static-core": "registry:dt/express-serve-static-core#0.0.0+20160322035842",
|
||||
"hapi": "registry:dt/hapi#13.0.0+20160521152637",
|
||||
"hapi": "registry:dt/hapi#13.0.0+20160602125023",
|
||||
"koa": "registry:dt/koa#2.0.0+20160317120654",
|
||||
"mime": "registry:dt/mime#0.0.0+20160316155526",
|
||||
"mocha": "registry:dt/mocha#2.2.5+20160317120654",
|
||||
"node": "registry:dt/node#6.0.0+20160524002506",
|
||||
"serve-static": "registry:dt/serve-static#0.0.0+20160501131543",
|
||||
"superagent": "registry:dt/superagent#1.4.0+20160317120654",
|
||||
"supertest-as-promised": "registry:dt/supertest-as-promised#2.0.2+20160317120654"
|
||||
"serve-static": "registry:dt/serve-static#0.0.0+20160501131543"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue