2017-12-11 21:13:35 -08:00
# GraphQL Server for Express, Connect, Hapi, Koa, and more
Also supports: Restify, Micro, Azure Functions, AWS Lambda and Adonis Framework
2016-04-24 16:00:42 -07:00
2017-07-17 16:29:40 -07:00
[](https://badge.fury.io/js/apollo-server-core)
[](https://travis-ci.org/apollographql/apollo-server)
2017-12-11 23:11:11 -08:00
[](https://www.apollographql.com/#slack )
2016-04-24 16:00:42 -07:00
2017-12-11 23:44:32 -08:00
Apollo Server is a community-maintained open-source GraphQL server. It works with pretty much all Node.js HTTP server frameworks, and we're happy to take PRs for more! Apollo Server works with any GraphQL schema built with [GraphQL.js ](https://github.com/graphql/graphql-js ), so you can build your schema with that directly or with a convenience library such as [graphql-tools ](https://www.apollographql.com/docs/graphql-tools/ ).
2016-04-24 16:00:42 -07:00
2017-12-11 21:14:32 -08:00
## Documentation
[Read the docs! ](https://www.apollographql.com/docs/apollo-server/ )
2016-08-01 12:54:47 -07:00
## Principles
2016-04-24 16:00:42 -07:00
2017-07-17 16:29:40 -07:00
Apollo Server is built with the following principles in mind:
2016-06-10 22:22:38 -07:00
2017-07-17 16:29:40 -07:00
* **By the community, for the community**: Apollo Server's development is driven by the needs of developers
* **Simplicity**: by keeping things simple, Apollo Server is easier to use, easier to contribute to, and more secure
* **Performance**: Apollo Server is well-tested and production-ready - no modifications needed
2016-06-10 22:22:38 -07:00
2017-07-17 16:29:40 -07:00
Anyone is welcome to contribute to Apollo Server, just read [CONTRIBUTING.md ](./CONTRIBUTING.md ), take a look at the [roadmap ](./ROADMAP.md ) and make your first PR!
2016-06-10 22:22:38 -07:00
2016-08-01 12:54:47 -07:00
## Getting started
2017-12-11 23:11:11 -08:00
Apollo Server is super easy to set up. Just `npm install apollo-server-<variant>` , write a GraphQL schema, and then use one of the following snippets to get started. For more info, read the [Apollo Server docs ](https://www.apollographql.com/docs/apollo-server/ ). To experiment a live example of Apollo Server, create an [Apollo Launchpad ](https://launchpad.graphql.com ). Downloading the pad will provide you a local Apollo Server project.
2016-08-01 12:54:47 -07:00
2016-09-29 17:46:40 +03:00
### Installation
2016-08-02 10:04:15 -07:00
2017-07-17 16:29:40 -07:00
Just run `npm install --save apollo-server-<variant>` and you're good to go!
2016-10-05 02:11:42 +03:00
2017-07-18 11:20:33 -07:00
where `<variant>` is one of the following:
2018-01-09 00:08:01 +01:00
* `express`
* `koa`
* `hapi`
* `restify`
* `lambda`
* `micro`
* `azure-functions`
* `adonis`
2016-08-02 10:40:40 -07:00
2016-08-01 12:54:47 -07:00
### Express
```js
import express from 'express';
2016-12-13 13:38:29 +01:00
import bodyParser from 'body-parser';
2017-09-25 19:44:42 -04:00
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';
2016-08-01 12:54:47 -07:00
const myGraphQLSchema = // ... define or import your schema here!
const PORT = 3000;
2017-06-25 10:51:10 +02:00
const app = express();
2016-08-01 12:54:47 -07:00
2016-11-14 23:45:45 +02:00
// bodyParser is needed just for POST.
2016-10-22 23:52:32 -07:00
app.use('/graphql', bodyParser.json(), graphqlExpress({ schema: myGraphQLSchema }));
2017-09-25 19:44:42 -04:00
app.get('/graphiql', graphiqlExpress({ endpointURL: '/graphql' })); // if you want GraphiQL enabled
2016-08-01 12:54:47 -07:00
app.listen(PORT);
```
### Connect
2018-01-09 00:08:01 +01:00
2016-08-01 12:54:47 -07:00
```js
2016-08-29 12:35:30 +02:00
import connect from 'connect';
2016-10-05 10:57:45 -05:00
import bodyParser from 'body-parser';
2017-11-09 10:03:45 -05:00
import query from 'connect-query';
2017-07-17 16:29:40 -07:00
import { graphqlConnect } from 'apollo-server-express';
2016-10-05 10:57:45 -05:00
import http from 'http';
2016-08-01 12:54:47 -07:00
const PORT = 3000;
2017-06-25 10:51:10 +02:00
const app = connect();
2016-08-01 12:54:47 -07:00
2017-11-09 10:03:45 -05:00
// bodyParser is only needed for POST.
2016-10-05 10:57:45 -05:00
app.use('/graphql', bodyParser.json());
2017-11-09 10:03:45 -05:00
// query is only needed for GET.
app.use('/graphql', query());
2016-10-22 23:52:32 -07:00
app.use('/graphql', graphqlConnect({ schema: myGraphQLSchema }));
2016-08-01 12:54:47 -07:00
2016-10-05 10:57:45 -05:00
http.createServer(app).listen(PORT);
2016-08-01 12:54:47 -07:00
```
2016-09-09 20:22:13 -05:00
### Hapi
2016-09-09 07:49:23 -05:00
2018-01-09 00:08:01 +01:00
Now with the Hapi plugins `graphqlHapi` and `graphiqlHapi` you can pass a route object that includes options to be applied to the route. The example below enables CORS on the `/graphql` route.
2016-09-09 07:49:23 -05:00
2017-12-08 00:04:12 -08:00
The code below requires Hapi 17 or higher.
2016-08-01 12:54:47 -07:00
```js
2017-12-08 00:04:12 -08:00
import Hapi from 'hapi';
2017-07-17 16:29:40 -07:00
import { graphqlHapi } from 'apollo-server-hapi';
2016-08-01 12:54:47 -07:00
const HOST = 'localhost';
const PORT = 3000;
2017-12-08 00:04:12 -08:00
async function StartServer() {
2018-01-09 00:08:01 +01:00
const server = new Hapi.server({
host: HOST,
port: PORT,
});
await server.register({
plugin: graphqlHapi,
options: {
path: '/graphql',
graphqlOptions: {
schema: myGraphQLSchema,
},
route: {
cors: true,
},
},
});
try {
await server.start();
} catch (err) {
console.log(`Error while starting server: ${err.message}` );
}
console.log(`Server running at: ${server.info.uri}` );
2017-12-08 00:04:12 -08:00
}
StartServer();
2016-08-01 12:54:47 -07:00
```
2016-09-09 07:49:23 -05:00
2016-08-01 12:54:47 -07:00
### Koa
2018-01-09 00:08:01 +01:00
2016-08-01 12:54:47 -07:00
```js
2016-12-14 07:40:52 -08:00
import koa from 'koa'; // koa@2
import koaRouter from 'koa-router'; // koa-router@next
2016-10-20 22:01:23 +03:00
import koaBody from 'koa-bodyparser'; // koa-bodyparser@next
2017-07-21 12:27:38 -04:00
import { graphqlKoa, graphiqlKoa } from 'apollo-server-koa';
2016-08-01 12:54:47 -07:00
const app = new koa();
const router = new koaRouter();
const PORT = 3000;
2016-11-14 23:45:45 +02:00
// koaBody is needed just for POST.
2017-07-23 16:41:29 +03:00
router.post('/graphql', koaBody(), graphqlKoa({ schema: myGraphQLSchema }));
2016-10-20 22:01:23 +03:00
router.get('/graphql', graphqlKoa({ schema: myGraphQLSchema }));
2016-11-14 23:45:45 +02:00
2017-07-21 12:27:38 -04:00
router.get('/graphiql', graphiqlKoa({ endpointURL: '/graphql' }));
2016-08-01 12:54:47 -07:00
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(PORT);
```
2016-10-24 11:04:18 -07:00
### Restify
2018-01-09 00:08:01 +01:00
2016-10-24 11:04:18 -07:00
```js
import restify from 'restify';
2017-07-17 16:29:40 -07:00
import { graphqlRestify, graphiqlRestify } from 'apollo-server-restify';
2016-10-24 11:04:18 -07:00
const PORT = 3000;
const server = restify.createServer({
2018-01-09 00:08:01 +01:00
title: 'Apollo Server',
2016-10-24 11:04:18 -07:00
});
2017-01-23 09:43:58 -08:00
const graphQLOptions = { schema: myGraphQLSchema };
2017-08-09 07:26:26 -04:00
server.use(restify.plugins.bodyParser());
server.use(restify.plugins.queryParser());
2016-10-24 11:04:18 -07:00
2017-01-23 09:43:58 -08:00
server.post('/graphql', graphqlRestify(graphQLOptions));
server.get('/graphql', graphqlRestify(graphQLOptions));
2016-10-24 11:04:18 -07:00
2017-01-22 11:56:35 -08:00
server.get('/graphiql', graphiqlRestify({ endpointURL: '/graphql' }));
2016-10-24 11:04:18 -07:00
server.listen(PORT, () => console.log(`Listening on ${PORT}` ));
```
2016-12-16 23:41:32 -06:00
### AWS Lambda
2017-10-02 08:25:58 -04:00
Lambda function should be run with [Node.js 4.3 or v6.1 ](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html#nodejs-prog-model-runtime-support-policy ). Requires an API Gateway with Lambda Proxy Integration.
2016-12-16 23:41:32 -06:00
```js
2018-01-09 00:08:01 +01:00
var server = require('apollo-server-lambda');
2016-12-16 23:41:32 -06:00
exports.handler = server.graphqlLambda({ schema: myGraphQLSchema });
```
2017-06-25 11:02:25 +02:00
### ZEIT Micro
2017-04-08 14:17:49 -07:00
2017-06-26 07:32:06 +02:00
Requires the [Micro ](https://github.com/zeit/micro ) module
2017-04-08 14:17:49 -07:00
```js
2018-01-09 00:08:01 +01:00
const server = require('apollo-server-micro');
2017-04-08 14:17:49 -07:00
module.exports = server.microGraphql({ schema: myGraphQLSchema });
```
2017-12-04 12:44:17 +03:00
### Adonis Framework
```js
// start/routes.js
const { graphqlAdonis } = require('apollo-server-adonis');
const Route = use('Route');
Route.post('/graphql', graphqlAdonis({ schema: myGraphQLSchema }));
Route.get('/graphql', graphqlAdonis({ schema: myGraphQLSchema }));
```
2016-08-01 12:54:47 -07:00
## Options
2017-07-22 09:32:10 +05:30
Apollo Server can be configured with an options object with the following fields:
2016-08-01 12:54:47 -07:00
* **schema**: the GraphQLSchema to be used
* **context**: the context value passed to resolvers during GraphQL execution
* **rootValue**: the value passed to the first resolve function
* **formatError**: a function to apply to every error before sending the response to clients
* **validationRules**: additional GraphQL validation rules to be applied to client-specified queries
* **formatParams**: a function applied for each query in a batch to format parameters before execution
* **formatResponse**: a function applied to each response after execution
2017-08-09 16:57:17 +02:00
* **tracing**: when set to true, collect and expose trace data in the [Apollo Tracing format ](https://github.com/apollographql/apollo-tracing )
2016-08-01 12:54:47 -07:00
All options except for `schema` are optional.
2016-08-20 20:33:20 -07:00
### Whitelisting
The `formatParams` function can be used in combination with the `OperationStore` to enable whitelisting.
```js
const store = new OperationStore(Schema);
store.put('query testquery{ testString }');
2016-10-22 23:52:32 -07:00
graphqlOptions = {
2018-01-09 00:08:01 +01:00
schema: Schema,
formatParams(params) {
params['query'] = store.get(params.operationName);
return params;
},
2016-08-20 20:33:20 -07:00
};
```
2017-07-18 11:17:57 -07:00
## Comparison with `express-graphql`
2016-08-01 12:54:47 -07:00
2017-07-18 11:17:57 -07:00
Both Apollo Server and [`express-graphql` ](https://github.com/graphql/express-graphql ) are GraphQL servers for Node.js, built on top of the [`graphql-js` reference implementation ](https://github.com/graphql/graphql-js ), but there are a few key differences:
2016-08-01 12:54:47 -07:00
2017-07-18 11:17:57 -07:00
* `express-graphql` works with Express and Connect, Apollo Server supports Express, Connect, Hapi, Koa and Restify.
* Compared to `express-graphql` , Apollo Server has a simpler interface and supports exactly one way of passing queries.
2017-07-18 11:20:33 -07:00
* Apollo Server separates serving [GraphiQL ](https://github.com/graphql/graphiql ) (an in-browser IDE for exploring GraphQL) from responding to GraphQL requests.
2017-07-18 11:17:57 -07:00
* `express-graphql` contains code for parsing HTTP request bodies, Apollo Server leaves that to standard packages like body-parser.
2017-07-18 11:07:31 -07:00
* Apollo Server includes an `OperationStore` to easily manage whitelisting.
* Apollo Server is built with TypeScript.
2016-09-10 18:37:14 -04:00
2017-03-10 10:37:12 +01:00
### application/graphql requests
2017-07-18 11:17:57 -07:00
`express-graphql` supports the `application/graphql` Content-Type for requests, which is an alternative to `application/json` request with only the query part sent as text. In the same way that we use `bodyParser.json` to parse `application/json` requests for apollo-server, we can use `bodyParser.text` plus one extra step in order to also parse `application/graphql` requests. Here's an example for Express:
2017-03-10 10:37:12 +01:00
```js
import express from 'express';
import bodyParser from 'body-parser';
2017-07-17 16:29:40 -07:00
import { graphqlExpress } from 'apollo-server-express';
2017-03-10 10:37:12 +01:00
const myGraphQLSchema = // ... define or import your schema here!
const helperMiddleware = [
bodyParser.json(),
bodyParser.text({ type: 'application/graphql' }),
(req, res, next) => {
if (req.is('application/graphql')) {
req.body = { query: req.body };
}
next();
}
];
express()
.use('/graphql', ...helperMiddleware, graphqlExpress({ schema: myGraphQLSchema }))
.listen(3000);
```
2017-07-17 16:29:40 -07:00
## Apollo Server Development
2016-09-10 18:37:14 -04:00
2017-07-17 16:29:40 -07:00
If you want to develop Apollo Server locally you must follow the following instructions:
2016-09-10 18:37:14 -04:00
* Fork this repository
2017-07-17 16:29:40 -07:00
* Install the Apollo Server project in your computer
2016-09-10 18:37:14 -04:00
```
2017-07-17 16:29:40 -07:00
git clone https://github.com/[your-user]/apollo-server
cd apollo-server
2016-10-05 02:32:12 +03:00
npm install
2017-07-17 16:29:40 -07:00
cd packages/apollo-server-< variant > /
2016-09-10 18:37:14 -04:00
npm link
```
2017-07-17 16:29:40 -07:00
* Install your local Apollo Server in other App
2016-09-10 18:37:14 -04:00
```
cd ~/myApp
2017-07-17 16:29:40 -07:00
npm link apollo-server-< variant >
2016-09-10 18:37:14 -04:00
```