diff --git a/integrations.md b/integrations.md new file mode 100644 index 000000000..745286138 --- /dev/null +++ b/integrations.md @@ -0,0 +1,31 @@ +# expressApollo + +An Express Middleware for the Apollo Server + +## Example Usage + +```js +import * as express from "express"; +import * as bodyParser from "body-parser"; +import { expressApollo } from "apollo-server"; +import schema from "./data/schema"; +import * as graphql from 'graphql' + +const port = 3000; +const app = express(); +const schema = new graphql.GraphQLSchema({ + query: new graphql.GraphQLObjectType({ + name: 'Query', + fields: { + testString: { type: graphql.GraphQLString } + } + }) +}); + +app.use(bodyParser.text()); +app.use("/", expressApollo({schema})); + +app.listen(port, () => { + console.log(`Server is listen on ${port}`); +}); +``` diff --git a/package.json b/package.json index b4bd69811..a82cc3f21 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "homepage": "https://github.com/apollostack/apollo-proxy#readme", "dependencies": { "es6-promise": "^3.2.1", + "express": "^4.13.4", "graphql": "^0.6.0", "source-map-support": "^0.4.0" }, @@ -56,5 +57,9 @@ }, "peerDependencies": { "graphql": "^0.6.0" + }, + "typings": "dist/index.d.ts", + "typescript": { + "definition": "dist/index.d.ts" } } diff --git a/src/core/runQuery.ts b/src/core/runQuery.ts index 9afca710f..ad68c06e5 100644 --- a/src/core/runQuery.ts +++ b/src/core/runQuery.ts @@ -7,6 +7,8 @@ import { execute, } from 'graphql'; +import { Promise } from 'es6-promise'; + export interface GqlResponse { data?: Object; errors?: Array; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 000000000..e83a2f956 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,3 @@ +import expressApollo from './integrations/expressApollo'; + +export { expressApollo }; diff --git a/src/integrations/expressApollo.test.ts b/src/integrations/expressApollo.test.ts new file mode 100644 index 000000000..3d0ffcab1 --- /dev/null +++ b/src/integrations/expressApollo.test.ts @@ -0,0 +1,43 @@ +import { + assert, +} from 'chai'; + +// XXX can be removed after tests are actually writen +/* tslint:disable:no-unused-variable */ +import { + GraphQLSchema, + GraphQLObjectType, + GraphQLString, +} from 'graphql'; + +import expressApollo from './expressApollo'; + +const QueryType = new GraphQLObjectType({ + name: 'QueryType', + fields: { + testString: { + type: GraphQLString, + resolve() { + return 'it works'; + }, + }, + }, +}); + +const Schema = new GraphQLSchema({ + query: QueryType, +}); +// XXX can be removed after tests are actually writen +/* tslint:enable:no-unused-variable */ + +describe('expressApollo', () => { + it('returns express middleware', () => { + // XXX can be removed after tests are actually writen + // tslint:disable-next-line:no-unused-variable + const query = `{ testString }`; + const middleware = expressApollo({ + schema: Schema, + }); + assert(typeof middleware === 'function'); + }); +}); diff --git a/src/integrations/expressApollo.ts b/src/integrations/expressApollo.ts new file mode 100644 index 000000000..c08a35f60 --- /dev/null +++ b/src/integrations/expressApollo.ts @@ -0,0 +1,29 @@ +import * as express from 'express'; +import * as graphql from 'graphql'; +import { runQuery } from '../core/runQuery'; + +export interface ExpressBindings { + schema: graphql.GraphQLSchema; +} + +export default function(options: ExpressBindings) { + if (!options) { + throw new Error('GraphQL middleware requires options.'); + } + + if (arguments.length > 1) { + throw new Error(`apolloServer expects exactly one argument, got ${arguments.length + 1}`); + } + + return (req: express.Request, res: express.Response, next) => { + runQuery({ + schema: options.schema, + query: req.body, + }).then(gqlResponse => { + res.set('Content-Type', 'application/json'); + res.send({ data: gqlResponse.data }); + }).catch(gqlResponse => { + res.send(gqlResponse.errorCode, { errors: gqlResponse.errors }); + }); + }; +} diff --git a/src/test/tests.ts b/src/test/tests.ts index fbf6335e4..a133ba2de 100644 --- a/src/test/tests.ts +++ b/src/test/tests.ts @@ -8,3 +8,4 @@ declare function require(name: string); require('source-map-support').install(); import '../core/runQuery.test'; +import '../integrations/expressApollo.test'; diff --git a/tsconfig.json b/tsconfig.json index 877ec8b84..14595d651 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es6", + "target": "es5", "module": "commonjs", "moduleResolution": "node", "sourceMap": true, diff --git a/typings.json b/typings.json index ced971d43..ab304d641 100644 --- a/typings.json +++ b/typings.json @@ -4,6 +4,7 @@ "graphql": "github:nitintutlani/typed-graphql" }, "globalDependencies": { + "es6-promise": "registry:dt/es6-promise#0.0.0+20160317120654", "body-parser": "registry:dt/body-parser#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",