├── assets └── theme-colors.less ├── source ├── logo │ ├── favicon.png │ ├── icon-apollo-white-200x200.png │ └── logo-apollo-space.svg ├── graphql-tools │ ├── graphiql-test.png │ ├── index.md │ ├── mocking.md │ ├── errors.md │ ├── connectors.md │ ├── resolvers.md │ ├── generate-schema.md │ └── scalars.md ├── apollo-server │ ├── graphiql-casual-mocks.png │ ├── index.md │ ├── migration-hapi.md │ ├── requests.md │ ├── graphiql.md │ ├── migration.md │ └── setup.md └── index.md ├── .gitignore ├── .gitmodules ├── README.md ├── circle.yml ├── package.json └── _config.yml /assets/theme-colors.less: -------------------------------------------------------------------------------- 1 | @color-primary: #22A699; 2 | -------------------------------------------------------------------------------- /source/logo/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/tools-docs/master/source/logo/favicon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | node_modules/ 6 | public/ 7 | .deploy*/ 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "themes/meteor"] 2 | path = themes/meteor 3 | url = https://github.com/meteor/hexo-theme-meteor.git 4 | -------------------------------------------------------------------------------- /source/graphql-tools/graphiql-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/tools-docs/master/source/graphql-tools/graphiql-test.png -------------------------------------------------------------------------------- /source/logo/icon-apollo-white-200x200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/tools-docs/master/source/logo/icon-apollo-white-200x200.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docs 2 | 3 | To run: 4 | 5 | ``` 6 | git submodule init 7 | git submodule update 8 | npm install 9 | npm start 10 | ``` 11 | -------------------------------------------------------------------------------- /source/apollo-server/graphiql-casual-mocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/tools-docs/master/source/apollo-server/graphiql-casual-mocks.png -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | node: 3 | version: 0.12 4 | 5 | checkout: 6 | post: 7 | - git submodule update --init 8 | 9 | dependencies: 10 | cache_directories: 11 | - "site/node_modules" 12 | override: 13 | - npm install -g hexo-cli 14 | - npm install 15 | 16 | test: 17 | override: 18 | # maybe we will need tests in the future 19 | - echo 'ok!' 20 | 21 | deployment: 22 | s3: 23 | branch: /^(master|version-.*)/ 24 | commands: 25 | - npm run deploy 26 | -------------------------------------------------------------------------------- /source/graphql-tools/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Overview 3 | order: 301 4 | description: How to install GraphQL Tools. 5 | --- 6 | 7 | GraphQL Tools is an npm package and an opinionated guide for how to build a GraphQL server in JavaScript. 8 | 9 | 10 | ```txt 11 | npm install graphql-tools graphql 12 | ``` 13 | 14 | Functions in the `graphql-tools` package are not just useful for building servers, but can also be used in the browser, for example to mock a backend during development or testing. Even though our guide recommends a specific way of building GraphQL servers, you can use these tools even if you don't follow our guide; they work with any GraphQL-JS schema, and each tool can be useful on its own. 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-site", 3 | "version": "0.0.0", 4 | "private": true, 5 | "hexo": { 6 | "version": "3.2.0" 7 | }, 8 | "dependencies": { 9 | "handlebars": "^4.0.5", 10 | "hexo": "3.2.0", 11 | "hexo-generator-archive": "^0.1.2", 12 | "hexo-generator-category": "^0.1.2", 13 | "hexo-generator-index": "^0.1.2", 14 | "hexo-generator-tag": "^0.1.1", 15 | "hexo-renderer-ejs": "^0.1.0", 16 | "hexo-renderer-less": "^0.2.0", 17 | "hexo-renderer-marked": "^0.2.4", 18 | "hexo-server": "^0.1.2", 19 | "lodash": "^4.13.1", 20 | "showdown": "^1.4.2" 21 | }, 22 | "devDependencies": { 23 | "hexo-s3-deploy": "^1.2.1" 24 | }, 25 | "scripts": { 26 | "start": "hexo serve", 27 | "deploy": "hexo-s3-deploy", 28 | "develop-theme": "nodemon -x 'rm db.json; hexo serve' -w assets/ -w code/ -w source/ -w themes/ -w scripts/" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /source/apollo-server/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Installing 3 | order: 201 4 | description: How to install Apollo Server 5 | --- 6 | 7 | Apollo Server is a community driven, flexible, production-ready HTTP JavaScript GraphQL server. You can use it with all popular JavaScript web servers, including Express, Connect, Hapi, and Koa. 8 | 9 | Install it with: 10 | 11 | ```txt 12 | npm install apollo-server 13 | ``` 14 | 15 | The following features distinguish Apollo Server from [express-graphql](https://github.com/graphql/express-graphql), Facebook's reference HTTP server implementation: 16 | 17 | - Apollo Server has a simpler interface and allows only one way of sending queries--POST requests--which makes it a bit easier to reason about what's going on. 18 | - Apollo Server serves GraphiQL on a separate route, giving you more flexibility to decide when and how to serve it. 19 | - Apollo Server supports [query batching](https://medium.com/apollo-stack/query-batching-in-apollo-63acfd859862) which can help reduce load on your server. 20 | - Apollo Server has built-in support for query whitelisting, which can make your app faster and your server more secure. 21 | -------------------------------------------------------------------------------- /source/apollo-server/migration-hapi.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Migrating from v0.2 3 | order: 206 4 | description: How to migrate from an older version of Apollo Server 5 | --- 6 | 7 | Version 0.3.0 of Apollo Server contains a couple of breaking changes in the Hapi plugin API. 8 | The most notable changes are: 9 | 10 | - the plugin class has been replaced as a function to be more idiomatic 11 | - the plugin name has been renamed to use camelcase 12 | - the options object has been extended to support additional routing options 13 | 14 | The following code snippet for Hapi Apollo 0.2.x 15 | 16 | ```js 17 | import { ApolloHAPI } from 'apollo-server'; 18 | ... 19 | server.register({ 20 | register: new ApolloHAPI(), 21 | options: { schema: myGraphQLSchema }, 22 | routes: { prefix: '/graphql' }, 23 | }); 24 | ``` 25 | 26 | ... should be written as follows for Hapi Apollo 0.3.x 27 | 28 | ```js 29 | import { apolloHapi } from 'apollo-server'; 30 | ... 31 | server.register({ 32 | register: apolloHapi, 33 | options: { 34 | path: '/graphql', 35 | apolloOptions: { 36 | schema: myGraphQLSchema, 37 | }, 38 | route: { 39 | cors: true 40 | } 41 | }, 42 | }); 43 | ``` 44 | 45 | *NOTE:* That you can now pass additional routing configuration via the route options 46 | -------------------------------------------------------------------------------- /source/apollo-server/requests.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sending requests 3 | order: 203 4 | description: How to send requests to Apollo Server 5 | --- 6 | 7 | Apollo Server accepts only JSON-encoded POST requests. A valid request must contain either a `query` or an `operationName` (or both, in case of a named query), and may include `variables.` For example: 8 | 9 | ```js 10 | { 11 | "query": "query aTest{ test(who: $arg1) }", 12 | "operationName": "aTest", 13 | "variables": { "arg1": "me" } 14 | } 15 | ``` 16 | 17 | Variables can be an object or a JSON-encoded string. I.e. the following is equivalent to the previous query: 18 | 19 | ```js 20 | { 21 | "query": "query aTest{ test(who: $arg1) }", 22 | "operationName": "aTest", 23 | "variables": "{ \"arg1\": \"me\" }" 24 | } 25 | ``` 26 | 27 | A batch of queries can be sent by simply sending a JSON-encoded array of queries, e.g. 28 | 29 | ```js 30 | [ 31 | { "query": "{ testString }" }, 32 | { "query": "query q2{ test(who: \"you\" ) }" } 33 | ] 34 | ``` 35 | 36 | If a batch of queries is sent, the response will be an array of GraphQL responses. 37 | 38 | If Apollo Server is running under a different origin than your client, you will need to enable CORS support on the server, or proxy the GraphQL requests through a web server under the main origin. 39 | -------------------------------------------------------------------------------- /source/graphql-tools/mocking.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Mocking 3 | order: 306 4 | description: Mock your GraphQL data based on a schema. 5 | --- 6 | 7 |

8 | mockServer(schema, mocks = {}, preserveResolvers = false) 9 |

10 | 11 | For more information about how to use the `mockServer` function, see the [Medium Post about mocking](https://medium.com/apollo-stack/mocking-your-server-with-just-one-line-of-code-692feda6e9cd). 12 | 13 |

14 | addMockFunctionsToSchema({schema, mocks = {}, preserveResolvers = false}) 15 |

16 | 17 | `addMockFunctionsToSchema` is the function that `mockServer` uses under the hood. Given an instance of GraphQLSchema and a mock object, it modifies the schema in place to return mock data for any valid query that is sent to the server. If `mocks` is not passed, the defaults will be used for each of the scalar types. If `preserveResolvers` is set to `true`, existing resolve functions will not be overwritten to provide mock data. This can be used to mock some parts of the server and not others. 18 | `mockServer` will set the `context` to `{}` when invoking `graphql`, which means that the mock functions could use that context to store additional information for mocking, such as relationships between different types. 19 | -------------------------------------------------------------------------------- /source/graphql-tools/errors.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Error handling and logging 3 | order: 308 4 | description: Add better error logging to your GraphQL schema. 5 | --- 6 | 7 | GraphQL servers can be tricky to debug. The following functions can help find error faster in many cases. 8 | 9 |

10 | forbidUndefinedInResolve(schema) 11 |

12 | 13 | ForbidUndefinedInResolve can be used during debugging to find mistakes in resolve functions faster. Usually, resolve functions only return undefined due to programmer error. `forbidUndefinedInResolve` takes a GraphQLSchema as input, and modifies it in place to throw an error when a resolve function returns undefined, telling you exactly which resolver returned undefined. 14 | ```js 15 | import { forbidUndefinedInResolve } from 'graphql-tools'; 16 | 17 | forbidUndefinedInResolve(schema); 18 | ``` 19 | 20 | 21 |

22 | addErrorLoggingToSchema(schema, logger) 23 |

24 | 25 | This function may be deprecated in the near future. Instead of using addErrorLoggingToSchema, the `formatError` option of `apolloServer` or `graphqlHTTP` should be used, which was recently added in graphql-js v0.5.0 26 | 27 | `addErorrLoggingToSchema` takes two arguments: `schema` and `logger`. `schema` must be an instance of `GraphQLSchema`, `logger` must be an Object with a callable property `log`. Every time an error occurs, `logger.log(e)` will be called. 28 | ```js 29 | import { addErrorLoggingToSchema } from 'graphql-tools'; 30 | const logger = { log: (e) => console.error(e.stack) }; 31 | addErrorLoggingToSchema(mySchema, logger); 32 | ``` 33 | -------------------------------------------------------------------------------- /source/graphql-tools/connectors.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Backend connectors 3 | order: 307 4 | description: Factor out your code data loading logic into connectors. 5 | --- 6 | 7 | Connectors are the parts that connect the GraphQL server to various backends, such as MySQL servers, MongoDB, Redis, REST, etc. The stores may be on the same server or on a different server, and the same GraphQL server may access a variety of different backend stores to get the data for just one request. 8 | 9 | Resolve functions act as a sort of switchboard, defining which connector should be used for which GraphQL types, and what arguments should be passed to it. While resolve functions should be stateless, connectors need to be stateful in many cases, for example to store information about the currently logged in user, or manage connections with the backend store. Because the same connector may be used in many resolve function, it has to be attached to the context, where all the resolve functions easily have access to it. 10 | 11 |

12 | attachConnectorsToContext(schema, connectors) 13 |

14 | 15 | `attachConnectorsToContext` takes two arguments: a GraphQLSchema and a `connectors` object that has connector classes as its named properties. The schema is modified in place such that for each query an instance of each connector will be constructed and attached to the context at the beginning of query execution, effectively making it a singleton that can keep state. 16 | 17 | ```js 18 | // in connectors.js 19 | import { attachConnectorsToContext } from 'graphql-tools'; 20 | 21 | class AuthorConnector{ 22 | constructor(){ 23 | this.store = new Map(); 24 | this.store.set(1, { id: 1, firstName: 'Bill', lastName: 'Nye' }); 25 | } 26 | 27 | get(key){ 28 | return this.store.get(key); 29 | } 30 | set(key, value){ 31 | return this.store.set(key, value); 32 | } 33 | } 34 | 35 | const connectors = { 36 | Author: AuthorConnector, 37 | }; 38 | 39 | attachConnectorsToContext(schema, connectors); 40 | 41 | 42 | // --- in a resolve function --- 43 | resolveAuthor(obj, args, context){ 44 | return context.connectors.Author.get(args.id); 45 | } 46 | ``` 47 | -------------------------------------------------------------------------------- /source/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction 3 | order: 0 4 | --- 5 | 6 | In addition to a set of fully-featured GraphQL clients, the Apollo community maintains a set of tools for building GraphQL servers and clients. 7 | 8 | ### GraphQL server tools 9 | 10 | These are tools designed to make it easy to build a JavaScript GraphQL server using [GraphQL.js](https://github.com/graphql/graphql-js), Facebook's reference implementation of a GraphQL type system and execution engine. 11 | 12 | - [Apollo Server](/tools/apollo-server), a production-ready Node.js GraphQL server library that supports Express, Connect, Hapi, Koa, and other popular Node HTTP servers, with built-in features like persisted queries, batching, and more. Apollo Server works with any GraphQL client, like Apollo, Relay, Lokka, and more. 13 | - [graphql-tools](/tools/graphql-tools), a package that provides an alternative approach to constructing a GraphQL.js schema using the GraphQL schema language, rather than using the GraphQL.js type constructors directly. Schemas built with this package are compatible with any GraphQL servers, including our own `apollo-server` and Facebook's `express-graphql`. 14 | - [graphql-subscriptions](https://github.com/apollostack/graphql-subscriptions), a transport-agnostic JavaScript utility that helps you execute GraphQL subscriptions and attach them to event sources. 15 | - [subscriptions-transport-ws](https://github.com/apollostack/subscriptions-transport-ws), a websocket server and client for GraphQL subscriptions that works with `graphql-subscriptions` and can be easily used directly in a JavaScript app or wired up to a fully-featured GraphQL client like Apollo or Relay. 16 | 17 | ### GraphQL client tools 18 | 19 | - [graphql-anywhere](https://github.com/apollostack/graphql-anywhere), the core schema-less GraphQL execution engine of the Apollo JavaScript Client, which lets you build your own powerful GraphQL tools and cache implementations, and works anywhere you can run JavaScript code. 20 | 21 | ### Developer tools 22 | 23 | - [eslint-plugin-graphql](https://github.com/apollostack/eslint-plugin-graphql), an ESLint plugin that will check your GraphQL query strings for syntax errors and schema compliance, and works with any JavaScript GraphQL client including Apollo, Relay, Lokka, and more. 24 | -------------------------------------------------------------------------------- /source/apollo-server/graphiql.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: GraphiQL 3 | order: 204 4 | description: How to set up GraphiQL with Apollo Server 5 | --- 6 | 7 | Apollo Server allows you to easily use [GraphiQL](https://github.com/graphql/graphiql). Here's how: 8 | 9 |

Configuring GraphiQL

10 | 11 | `graphiql` accepts the following options object: 12 | 13 | ```js 14 | const options = { 15 | endpointUrl: String, // URL for the GraphQL endpoint this instance of GraphiQL serves 16 | query?: String, // optional query to pre-populate the GraphiQL UI with 17 | operationName?: String, // optional operationName to pre-populate the GraphiQL UI with 18 | variables?: Object, // optional variables to pre-populate the GraphiQL UI with 19 | result?: Object, // optional result to pre-populate the GraphiQL UI with 20 | } 21 | ``` 22 | 23 | Apollo Server's `graphiql` middleware does not run any query passed to it, it simply renders it in the UI. 24 | To actually execute the query, the user must submit it via the GraphiQL UI, which will 25 | send the request to the GraphQL endpoint specified with `endpointURL`. 26 | 27 |

Using with Express

28 | 29 | If you are using Express, GraphiQL can be configured as follows: 30 | 31 | ```js 32 | import { graphiqlExpress } from 'apollo-server'; 33 | 34 | app.use('/graphiql', graphiqlExpress({ 35 | endpointURL: '/graphql', 36 | })); 37 | ``` 38 | 39 | 40 |

Using with Connect

41 | 42 | If you are using Connect, GraphiQL can be configured as follows: 43 | 44 | ```js 45 | import { graphiqlConnect } from 'apollo-server'; 46 | 47 | app.use('/graphiql', graphiqlConnect({ 48 | endpointURL: '/graphql', 49 | })); 50 | ``` 51 | 52 | 53 |

Using with Hapi

54 | 55 | If you are using Hapi, GraphiQL can be configured as follows: 56 | 57 | ```js 58 | import { graphiqlHapi } from 'apollo-server'; 59 | 60 | server.register({ 61 | register: graphiqlHapi, 62 | options: { 63 | path: '/graphiql', 64 | graphiqlOptions: { 65 | endpointURL: '/graphql', 66 | }, 67 | }, 68 | }); 69 | ``` 70 | 71 | 72 |

Using with Koa 2

73 | 74 | If you are using Koa 2, GraphiQL can be configured as follows: 75 | 76 | ```js 77 | import { graphiqlKoa } from 'apollo-server'; 78 | 79 | router.get('/graphiql', graphiqlKoa({ endpointURL: '/graphql' })); 80 | ``` 81 | -------------------------------------------------------------------------------- /source/graphql-tools/resolvers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Adding resolvers 3 | order: 305 4 | description: Add resolvers to a GraphQL schema. 5 | --- 6 | 7 | ## Resolve functions 8 | In order to respond to queries, a schema needs to have resolve functions. Resolve functions cannot be included in the GraphQL schema language, so they must be added separately. 9 | 10 |

11 | addResolveFunctionsToSchema(schema, resolveFunctions) 12 |

13 | 14 | `addResolveFunctionsToSchema` takes two arguments, a GraphQLSchema and an object defining resolve functions, and modifies the schema in place to. The `resolveFunctions` object should have one property for each type that has fields which need a resolve function. The following is an example of a valid resolveFunctions object: 15 | ```js 16 | import { addResolveFunctionsToSchema } from 'graphql-tools'; 17 | 18 | const resolveFunctions = { 19 | RootQuery: { 20 | author(root, { name }){ 21 | return Author.find({ name }); 22 | }, 23 | }, 24 | }; 25 | 26 | addResolveFunctionsToSchema(schema, resolveFunctions); 27 | ``` 28 | 29 | For types which need to define additional properties, such as `resolveType` for unions and interfaces, the property can be set by prefixing it with two underscores, eg. `__resolveType` for `resolveType`: 30 | 31 | ```js 32 | const resolveFunctions = { 33 | SomeUnionType: { 34 | __resolveType(data, context, info){ 35 | if(data.wingspan){ 36 | return info.schema.getType('Airplane'); 37 | } 38 | if(data.horsepower){ 39 | return info.schema.getType('Car'); 40 | } 41 | return null; 42 | }, 43 | }, 44 | }; 45 | ``` 46 | Note that if the types were defined in GraphQL schema language, the `info` argument to `resolveType` must be used to get a reference to the actual type, eg. `return info.schema.getType("Person")`. This may be changed in the future to support returning just the name of the type, eg. `return "Person"`. 47 | 48 |

49 | addSchemaLevelResolveFunction(schema, rootResolveFunction) 50 |

51 | 52 | Some operations, such as authentication, need to be done only once per query. Logically, these operations belong in a root resolve function, but unfortunately GraphQL-JS does not let you define one. `addSchemaLevelResolveFunction` solves this by modifying the GraphQLSchema that is passed as the first argument. 53 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: http://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: Apollo Tools Guide 7 | subtitle: A guide to using the Apollo GraphQL Tools. 8 | description: 9 | author: 10 | language: 11 | timezone: 12 | versions: 13 | - '1' 14 | sidebar_categories: 15 | null: 16 | - index 17 | Apollo Server: 18 | - apollo-server/index 19 | - apollo-server/setup 20 | - apollo-server/requests 21 | - apollo-server/graphiql 22 | - apollo-server/migration 23 | GraphQL Tools: 24 | - graphql-tools/index 25 | # - graphql-tools/guide 26 | # - graphql-tools/tools 27 | - graphql-tools/generate-schema 28 | - graphql-tools/resolvers 29 | - graphql-tools/scalars 30 | - graphql-tools/mocking 31 | - graphql-tools/connectors 32 | - graphql-tools/errors 33 | github_repo: apollostack/server-docs 34 | content_root: source 35 | 36 | social_links: 37 | github: 'https://github.com/apollostack' 38 | twitter: '@apollostack' 39 | 40 | # API keys 41 | apis: 42 | segment: wgrIo8Bul0Ujl8USETG3DB6hONdy4kTg 43 | 44 | # URL 45 | ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' 46 | url: http://dev.apollodata.com/tools 47 | root: /tools/ 48 | permalink: :year/:month/:day/:title/ 49 | permalink_defaults: 50 | 51 | # Directory 52 | source_dir: source 53 | public_dir: public 54 | tag_dir: tags 55 | archive_dir: archives 56 | category_dir: categories 57 | code_dir: downloads/code 58 | i18n_dir: :lang 59 | skip_render: 60 | 61 | # Writing 62 | new_post_name: :title.md # File name of new posts 63 | default_layout: post 64 | titlecase: false # Transform title into titlecase 65 | external_link: true # Open external links in new tab 66 | filename_case: 0 67 | render_drafts: false 68 | post_asset_folder: false 69 | relative_link: false 70 | future: true 71 | highlight: 72 | enable: true 73 | line_number: true 74 | auto_detect: true 75 | tab_replace: 76 | 77 | # Category & Tag 78 | default_category: uncategorized 79 | category_map: 80 | tag_map: 81 | 82 | # Date / Time format 83 | ## Hexo uses Moment.js to parse and display date 84 | ## You can customize the date format as defined in 85 | ## http://momentjs.com/docs/#/displaying/format/ 86 | date_format: YYYY-MM-DD 87 | time_format: HH:mm:ss 88 | 89 | # Pagination 90 | ## Set per_page to 0 to disable pagination 91 | per_page: 10 92 | pagination_dir: page 93 | 94 | # Extensions 95 | ## Plugins: http://hexo.io/plugins/ 96 | ## Themes: http://hexo.io/themes/ 97 | theme: meteor 98 | 99 | # Deployment 100 | ## Docs: http://hexo.io/docs/deployment.html 101 | deploy: 102 | type: 103 | -------------------------------------------------------------------------------- /source/logo/logo-apollo-space.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 11 | 12 | 13 | 16 | 20 | 23 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /source/apollo-server/migration.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Migrating from v0.1 3 | order: 205 4 | description: How to migrate from an older version of Apollo Server 5 | --- 6 | 7 | Version 0.2.0 of Apollo Server contains several breaking changes in the API. 8 | The most notable changes are: 9 | 10 | - the `apolloServer` function no longer exists and was replaced with `apolloExpress`. 11 | - `apolloExpress` no longer accepts shorthand type definitions 12 | - `apolloExpress` doesn't have the `resolvers`, `mocks` and `connectors` options. 13 | - `apolloExpress` doesn't include GraphiQL any more 14 | - `context`: if you use connectors in your schema, don't forget to setup default `context` to at least an empty object, it can't be `undefined` in this case 15 | - Apollo Server no longer accepts GET requests or parameters in the URL 16 | - `apolloExpress` no longer parses the HTTP body automatically 17 | 18 | 19 | In order to make updating from an older version of Apollo Server easier, this guide 20 | shows how to use `graphql-tools` together with `apolloExpress` and `graphiqlExpress` to 21 | replace the old `apolloServer` function. 22 | 23 | The three main differences between the old and the new approach are: 24 | 1. generating the schema is now done with `graphql-tools`, Apollo Server only uses the finished schema. 25 | 2. `bodyParser` has to be used to parse requests before passing them to `expressApollo` 26 | 3. GraphiQL now has to be served on a separate path 27 | 28 | The following code snippet in Apollo Server 0.1.x 29 | 30 | ```js 31 | import express from 'express'; 32 | import { apolloServer } from 'apollo-server'; 33 | import Schema from './data/schema'; 34 | import Mocks from './data/mocks'; 35 | import Resolvers from './data/resolvers'; 36 | import Connectors from './data/connectors'; 37 | 38 | const GRAPHQL_PORT = 8080; 39 | 40 | const graphQLServer = express(); 41 | 42 | graphQLServer.use('/graphql', apolloServer({ 43 | graphiql: true, 44 | schema: Schema, 45 | resolvers: Resolvers, 46 | connectors: Connectors, 47 | mocks: Mocks, 48 | })); 49 | 50 | graphQLServer.listen(GRAPHQL_PORT, () => console.log( 51 | `GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}/graphql` 52 | )); 53 | ``` 54 | 55 | ... should be written as follows in Apollo Server 0.2.x and above: 56 | 57 | 58 | ```js 59 | import express from 'express'; 60 | 61 | import Schema from './data/schema'; 62 | import Mocks from './data/mocks'; 63 | import Resolvers from './data/resolvers'; 64 | import Connectors from './data/connectors'; 65 | 66 | // NEW or changed imports: 67 | import { apolloExpress, graphiqlExpress } from 'apollo-server'; 68 | import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools'; 69 | import bodyParser from 'body-parser'; 70 | 71 | 72 | 73 | const GRAPHQL_PORT = 8080; 74 | 75 | const graphQLServer = express(); 76 | 77 | const executableSchema = makeExecutableSchema({ 78 | typeDefs: Schema, 79 | resolvers: Resolvers, 80 | connectors: Connectors, 81 | }); 82 | 83 | addMockFunctionsToSchema({ 84 | schema: executableSchema, 85 | mocks: Mocks, 86 | preserveResolvers: true, 87 | }); 88 | 89 | // `context` must be an object and can't be undefined when using connectors 90 | graphQLServer.use('/graphql', bodyParser.json(), apolloExpress({ 91 | schema: executableSchema, 92 | context: {}, //at least(!) an empty object 93 | })); 94 | 95 | graphQLServer.use('/graphiql', graphiqlExpress({ 96 | endpointURL: '/graphql', 97 | })); 98 | 99 | graphQLServer.listen(GRAPHQL_PORT, () => console.log( 100 | `GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}/graphql` 101 | )); 102 | ``` 103 | -------------------------------------------------------------------------------- /source/apollo-server/setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Adding a GraphQL endpoint 3 | order: 202 4 | description: How to set up Apollo Server 5 | --- 6 | 7 | Apollo Server exports the `apolloExpress`, `apolloConnect`, `apolloHapi` and `apolloKoa` functions which can be used to add a GraphQL HTTP endpoint to your Express, Connect, Hapi or Koa 2 server. 8 | 9 |

Apollo Server options

10 | 11 | Apollo Server accepts an ApolloOptions object as its single argument. An ApolloOptions object has the following properties: 12 | 13 | ```js 14 | // options object 15 | const ApolloOptions = { 16 | schema: GraphQLSchema, 17 | 18 | // values to be used as context and rootValue in resolvers 19 | context?: any, 20 | rootValue?: any, 21 | 22 | // function used to format errors before returning them to clients 23 | formatError?: Function, 24 | 25 | // additional validation rules to be applied to client-specified queries 26 | validationRules?: Array, 27 | 28 | // function applied for each query in a batch to format parameters before passing them to `runQuery` 29 | formatParams?: Function, 30 | 31 | // function applied to each response before returning data to clients 32 | formatResponse?: Function, 33 | 34 | // a boolean option that will trigger additional debug logging if execution errors occur 35 | debug?: boolean 36 | }) 37 | ``` 38 | 39 | Alternatively, Apollo Server can accept a function which takes the request as input and returns an ApolloOptions object or a promise that resolves to one: 40 | 41 | ```js 42 | // example options function (for express) 43 | apolloExpress(request => ({ 44 | schema: typeDefinitionArray, 45 | context: { user: request.session.user } 46 | })) 47 | ``` 48 | 49 |

Using with Express

50 | 51 | The following code snippet shows how to use Apollo Server with Express: 52 | 53 | ```js 54 | import express from 'express'; 55 | import bodyParser from 'body-parser'; 56 | import { apolloExpress } from 'apollo-server'; 57 | 58 | const PORT = 3000; 59 | 60 | var app = express(); 61 | 62 | app.use('/graphql', bodyParser.json(), apolloExpress({ schema: myGraphQLSchema })); 63 | 64 | app.listen(PORT); 65 | ``` 66 | 67 |

Using with Connect

68 | 69 | The following code snippet shows how to use Apollo Server with Connect: 70 | 71 | ```js 72 | import connect from 'express'; 73 | import bodyParser from 'body-parser'; 74 | import { apolloConnect } from 'apollo-server'; 75 | 76 | const PORT = 3000; 77 | 78 | var app = connect(); 79 | 80 | app.use('/graphql', bodyParser.json(), apolloConnect({ schema: myGraphQLSchema })); 81 | 82 | app.listen(PORT); 83 | ``` 84 | 85 | The `options` passed to `apolloConnect` are the same as those passed to `apolloExpress`. 86 | 87 | 88 |

Using with Hapi

89 | 90 | The following code snippet shows how to use Apollo Server with Hapi: 91 | 92 | ```js 93 | import hapi from 'hapi'; 94 | import { apolloHapi } from 'apollo-server'; 95 | 96 | const server = new hapi.Server(); 97 | 98 | const HOST = 'localhost'; 99 | const PORT = 3000; 100 | 101 | server.connection({ 102 | host: HOST, 103 | port: PORT, 104 | }); 105 | 106 | server.register({ 107 | register: apolloHapi, 108 | options: { 109 | path: '/graphql', 110 | apolloOptions: { schema: myGraphQLSchema }, 111 | }, 112 | }); 113 | ``` 114 | 115 | 116 |

Using with Koa 2

117 | 118 | The following code snippet shows how to use Apollo Server with Koa: 119 | 120 | ```js 121 | import koa from 'koa'; 122 | import koaRouter from 'koa-router'; 123 | import koaBody from 'koa-bodyparser'; 124 | import { apolloKoa } from 'apollo-server'; 125 | 126 | const app = new koa(); 127 | const router = new koaRouter(); 128 | const PORT = 3000; 129 | 130 | app.use(koaBody()); 131 | 132 | router.post('/graphql', apolloKoa({ schema: myGraphQLSchema })); 133 | app.use(router.routes()); 134 | app.use(router.allowedMethods()); 135 | app.listen(PORT); 136 | ``` 137 | -------------------------------------------------------------------------------- /source/graphql-tools/generate-schema.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Generating a schema 3 | order: 304 4 | description: Generate a GraphQL schema from the concise type definition language. 5 | --- 6 | 7 | The graphql-tools package allows you to create a GraphQLSchema instance from GraphQL schema language by using the function `makeExecutableSchema`. 8 | 9 |

makeExecutableSchema(option)

10 | 11 | ``` 12 | import { makeExecutableSchema } from 'graphql-tools'; 13 | 14 | const jsSchema = makeExecutableSchema({ 15 | typeDefs, 16 | resolvers, 17 | connectors, 18 | logger, 19 | allowUndefinedInResolve = false, //optional 20 | resolverValidationOptions = {}, //optional 21 | }); 22 | ``` 23 | 24 | `typeDefs` is a required argument and should be an array of GraphQL schema language strings or a function that takes no arguments and returns an array of GraphQL schema language strings. The order of the strings in the array is not important, but it must include a schema definition. 25 | 26 | `resolvers` is a required argument and should be an object that follows the pattern explained in the guide [section on resolvers](http://docs.apollostack.com/apollo-server/resolvers.html). 27 | 28 | `connectors` is an optional argument, which will take an object with connectors and attach them to the context of every resolve function. If this argument is provided, a `context` object must be passed to the `apollo{Express/Connect/Hapi/Koa}` call. See the [connector docs](http://docs.apollostack.com/graphql-tools/connectors.html) for more information. 29 | 30 | `logger` is an optional argument, which can be used to print errors to the server console that are usually swallowed by GraphQL. The `logger` argument should be an object with a `log` function, eg. `const logger = { log: (e) => console.log(e) }` 31 | 32 | `allowUndefinedInResolve` is an optional argument, which is `false` by default, and causes your resolve function to throw an error, if they return undefined. This can help make debugging easier. To get the default behavior of GraphQL, set this option to `true`. 33 | 34 | `resolverValidationOptions` is an optional argument which accepts an object of the following shape: `{ requireResolversForArgs, requireResolversForNonScalar }`. If set to true, `requireResolversForArgs` will cause `makeExecutableSchema` to throw an error, if no resolve function is defined for a field that has arguments. Similarly, `requireResolversForNonScalar` will cause `makeExecutableSchema` to throw an error if a non-scalar field has no resolver defined. By default, both of these are true, which can help catch errors faster. To get the normal behavior of GraphQL, set both of them to `false`. 35 | 36 | The type definitions must define a query type, which means a minimal schema would look something like this: 37 | ```js 38 | const typeDefinition = [` 39 | schema { 40 | query: RootQuery 41 | } 42 | 43 | type RootQuery { 44 | aNumber: Int 45 | } 46 | `]; 47 | ``` 48 | 49 | If your schema gets large, you may want to define parts of it in different files and import them to create the full schema. This is possible by including them in the array. If there are circular dependencies, the array should be wrapped in arrow function. `makeExecutableSchema` will only include each type definition once, even if it is imported multiple times by different types. 50 | 51 | ```js 52 | // in author.js ------------------- 53 | import Book from './book'; 54 | 55 | const Author = ` 56 | type Author { 57 | name: String 58 | books: [Book] 59 | } 60 | `; 61 | 62 | // we export have to export Author and all types it depends on in order to make it reusable 63 | export default () => [Author, Book]; 64 | ``` 65 | 66 | ```js 67 | // in book.js ----------------------- 68 | import Author from './author'; 69 | 70 | const Book = ` 71 | type Book { 72 | title: String 73 | author: Author 74 | } 75 | `; 76 | 77 | export default () => [Book, Author]; 78 | ``` 79 | 80 | ```js 81 | // in schema.js ---------------------- 82 | import Author from './author.js'; 83 | 84 | const RootQuery = ` 85 | type RootQuery { 86 | author(name: String): Author 87 | } 88 | `; 89 | 90 | const SchemaDefinition = ` 91 | schema { 92 | query: RootQuery 93 | } 94 | `; 95 | 96 | export default makeExecutableSchema([SchemaDefinition, RootQuery, Author], {}); 97 | ``` 98 | 99 | This [GraphQL schema language cheat sheet](https://raw.githubusercontent.com/sogko/graphql-shorthand-notation-cheat-sheet/master/graphql-shorthand-notation-cheat-sheet.png) by Hafiz Ismail is an excellent reference for all the features of the GraphQL schema language. 100 | -------------------------------------------------------------------------------- /source/graphql-tools/scalars.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Custom Scalars 3 | order: 309 4 | description: Add custom scalars to a GraphQL schema. 5 | --- 6 | 7 | ## Custom scalars 8 | 9 | The GraphQL language comes with the following pre-defined scalar types: `String`, `Int`, `Float` and `Boolean`. While this covers most of the user cases, often you need to support custom atomic data types (e.g. Date), or you need to add validations to existing types. As a result, GraphQL allows you to define custom `scalar`s that undertake this role. 10 | 11 | To define a custom scalar you simply add it to the schema with the following notation: 12 | 13 | ```js 14 | scalar MyCustomScalar 15 | ``` 16 | 17 | Consequently, you need to define the behaviour of the scalar: how it will be serialized when the value is sent to the client, and how the value is resolved when received from the client. For this purpose, each scalar needs to define three methods. In schemas defined with `graphql-tools` they are named `__serialize`, `__parseValue` and `__parseLiteral`. (If you're using `graphql-js` directly, the methods do not have the `__` prefix.) 18 | 19 | Note that [Apollo Client does not currently support custom scalars](https://github.com/apollostack/apollo-client/issues/585), so there's no way to automatically apply the same transformations on the client side. 20 | 21 | Let's look at a couple of examples to demonstrate the potential of custom scalars. 22 | 23 | ### Date as a scalar 24 | 25 | The goal is to define a `Date` data type for storing `Date` values in the database. We're using a MongoDB driver that uses the native JavaScript `Date` data type. The `Date` data type can be easily serialized as a number using the [`getTime()` method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime). Therefore, the GraphQL server will send and receive `Date`s as numbers. This number will be resolved to a `Date` on the server representing the date value. On the client, the user can simply create a new date from the received numeric value. 26 | 27 | The following is the implementation of the `Date` data type. First, the schema: 28 | 29 | ```js 30 | scalar Date 31 | 32 | type MyType { 33 | created: Date 34 | } 35 | ``` 36 | 37 | Next, the resolver: 38 | 39 | ```js 40 | import { Kind } from 'graphql/language'; 41 | 42 | Date: { 43 | __parseValue(value) { 44 | return new Date(value); // value from the client 45 | }, 46 | __serialize(value) { 47 | return value.getTime(); // value sent to the client 48 | }, 49 | __parseLiteral(ast) { 50 | if (ast.kind === Kind.INT) { 51 | return parseInt(ast.value, 10); // ast value is always in string format 52 | } 53 | return null; 54 | }, 55 | } 56 | ``` 57 | 58 | ### Validations 59 | 60 | In this example, we follow the [official GraphQL documentation](http://graphql.org/docs/api-reference-type-system/) for the scalar datatype. Let's say that you have a database field that should only contain odd numbers. First, the schema: 61 | 62 | ```js 63 | scalar Odd 64 | 65 | type MyType { 66 | oddValue: Odd 67 | } 68 | ``` 69 | 70 | Next, the resolver: 71 | 72 | ```js 73 | import { Kind } from 'graphql/language'; 74 | 75 | Odd: { 76 | __serialize: oddValue, 77 | __parseValue: oddValue, 78 | __parseLiteral(ast) { 79 | if (ast.kind === Kind.INT) { 80 | return oddValue(parseInt(ast.value, 10)); 81 | } 82 | return null; 83 | } 84 | } 85 | 86 | function oddValue(value) { 87 | return value % 2 === 1 ? value : null; 88 | } 89 | ``` 90 | 91 | ### JSON as a scalar 92 | 93 | While we usually want to define a schema for our data, in some cases it makes sense to store unstructured objects in the database and not define a GraphQL schema for it. JSON is a commonly used format for storing such objects. In GraphQL, we can define a custom scalar type to serialize and parse JSON: 94 | 95 | 96 | ```js 97 | scalar JSON 98 | 99 | type MyType { 100 | jsonField: JSON 101 | } 102 | ``` 103 | 104 | And the implementation of the resolver: 105 | 106 | ```js 107 | import { Kind } from 'graphql/language'; 108 | 109 | function parseJSONLiteral(ast) { 110 | switch (ast.kind) { 111 | case Kind.STRING: 112 | case Kind.BOOLEAN: 113 | return ast.value; 114 | case Kind.INT: 115 | case Kind.FLOAT: 116 | return parseFloat(ast.value); 117 | case Kind.OBJECT: { 118 | const value = Object.create(null); 119 | ast.fields.forEach(field => { 120 | value[field.name.value] = parseJSONLiteral(field.value); 121 | }); 122 | 123 | return value; 124 | } 125 | case Kind.LIST: 126 | return ast.values.map(parseJSONLiteral); 127 | default: 128 | return null; 129 | } 130 | } 131 | 132 | const resolvers = 133 | JSON: { 134 | __parseLiteral: parseJSONLiteral, 135 | __serialize: value => value, 136 | __parseValue: value => value, 137 | }, 138 | }; 139 | ``` 140 | 141 | For more information please refer to the [official documentation](http://graphql.org/docs/api-reference-type-system/) or to the [Learning GraphQL](https://github.com/mugli/learning-graphql/blob/master/7.%20Deep%20Dive%20into%20GraphQL%20Type%20System.md) tutorial. 142 | --------------------------------------------------------------------------------