1 | <img title="graphql-logo" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/GraphQL_Logo.svg/512px-GraphQL_Logo.svg.png" width="auto" height="250">
|
2 |
|
3 | # @apollo-waterline/server
|
4 |
|
5 | Fully-featured GraphQL Server with focus on easy setup, performance & great developer experience
|
6 | ## Breaking changes
|
7 | This library is shifted to Apollo Server 2.0 and is not using graphql-yoga by prisma anymore, because of their usage of Apollo Server 1.0.
|
8 | Apollo Server 2.0 is much improved in many ways and took over some best practices from graphql-yoga. As an example of the Apollo Server 2.0, the error handling is much improoved. So you can create Error Codes, you may pass along to the client to generate i18n language depeneded Error Message. [Apollo Error Handling](https://www.apollographql.com/docs/apollo-server/features/errors/)
|
9 |
|
10 | Actually, this Application now is also capable to be used with Apollo 2.0 Gateway, to create one API Gateway to hook together multiple Graphql Services (Micro Services), according to use the federated Schema ( [What is Apollo Federation?](https://www.apollographql.com/docs/apollo-server/federation/introduction/) ).
|
11 | You are also able to use Managed federation: [Announcing managed federation](https://blog.apollographql.com/announcing-managed-federation-265c9f0bc88e).
|
12 |
|
13 | Full Documentation of Apollo you may find [here: Apollo Docs](https://www.apollographql.com/docs/apollo-server/)
|
14 |
|
15 | ## Overview
|
16 |
|
17 | [<img title="waterline-logo" src="http://i.imgur.com/3Xqh6Mz.png" width="610px" alt="Waterline logo"/>](http://waterlinejs.org)
|
18 |
|
19 | An easy implementation of the [Apollo Server 2.x](https://www.apollographql.com/) server, but enhanced with an super easy usage of the great [Waterline ORM](http://waterlinejs.org/).
|
20 |
|
21 | ## Features
|
22 |
|
23 | Build your Models as used with Sails.JS.
|
24 | Auto Generation auf Model Schemas during Boot
|
25 | Resolver Context is enhanced with Waterline ORM instance `ctx.db`
|
26 | Usage or Waterline Adapters (Official and Community)
|
27 |
|
28 | ### Officially-supported database adapters
|
29 |
|
30 | - MySQL
|
31 | - PostgreSQL
|
32 | - MongoDB
|
33 | - Local disk / memory
|
34 | - ...[see more here](https://sailsjs.com/documentation/concepts/extending-sails/adapters/available-adapters)
|
35 |
|
36 | ### Community-supported database adapters:
|
37 |
|
38 | Is your database not supported by one of the core adapters? Good news! There are many different community database adapters for Sails.js and Waterline [available on NPM](https://www.npmjs.com/search?q=sails+adapter).
|
39 |
|
40 | Here are a few highlights:
|
41 |
|
42 | - Redis
|
43 | - MS SQL Server
|
44 | - OrientDB
|
45 | - Oracle
|
46 | - Oracle (AnyPresence)
|
47 | - Oracle (stored procedures)
|
48 | - SAP HANA DB
|
49 | - SAP HANA (AnyPresence)
|
50 | - IBM DB2
|
51 | - ServiceNow SOAP
|
52 | - Cassandra
|
53 | - Solr
|
54 | - FileMaker Database
|
55 | - Apache Derby
|
56 | - REST API (Generic)
|
57 | - ...[see more here](https://sailsjs.com/documentation/concepts/extending-sails/adapters/available-adapters#communitysupported-database-adapters)
|
58 |
|
59 | ### Injection of Waterline ORM in Resolver Context
|
60 |
|
61 | ```js
|
62 | // a resolver example with injected Waterline ORM
|
63 | Query = {
|
64 | myResolver = async (_, args, ctx) => {
|
65 | const UserModel = ctx.db.model("User");
|
66 | return await UserModel.find();
|
67 | }
|
68 | }
|
69 | ```
|
70 |
|
71 | ### Auto generation of Model Schemas based on your Waterline Models
|
72 |
|
73 | During the fist boot of the app, a folder structure ist created in your project root.
|
74 |
|
75 | ```text
|
76 | root/
|
77 | api/
|
78 | models/
|
79 | policies/
|
80 | resolvers/
|
81 | index.js
|
82 | schema/
|
83 | models.graphql
|
84 | schema.graphql
|
85 |
|
86 | config/
|
87 | adapter.js
|
88 | bootstrap.js
|
89 | datastores.js
|
90 | models.js
|
91 | settings.js
|
92 |
|
93 | yourApp.js // this file is not generated
|
94 | ```
|
95 |
|
96 | ## Usage
|
97 |
|
98 | The module returns a Promise. So it is easy to imolement in an asynchronus stack. Event with async / await.
|
99 | the promise is resolved with: `{server, db, express}`.
|
100 | So you have access to the server-instsance, de Waterline ORM and the express-application.
|
101 |
|
102 | ```js
|
103 | const yogaServer = require("@apollo-waterline/server");
|
104 |
|
105 | // use async / await for more easy reading
|
106 | (async () => {
|
107 | // config für gql
|
108 | const graphQLServerOpts = {};
|
109 |
|
110 | // config für server
|
111 | const bootOpts = {
|
112 | endpoint: "/graphql",
|
113 | port: 4000,
|
114 | playground: false
|
115 | };
|
116 | const server = await yogaServer(graphQLServerOpts);
|
117 |
|
118 | // get express instance
|
119 | const express = server.express;
|
120 |
|
121 | // modify express instance
|
122 | express.use("/myEndpoint", (req, res) => {
|
123 | res.send("OK");
|
124 | });
|
125 |
|
126 | // boot the server and thet the result
|
127 | const { port } = await server.boot(bootOpts);
|
128 | console.log(`Server is running on port: ${port}`);
|
129 | })();
|
130 | ```
|
131 |
|
132 | ### graphQlServerConfig
|
133 |
|
134 | ```js
|
135 | var aContextServiceProcvoder = requrie("my-service-provider");
|
136 |
|
137 | // for furthor information see: https://www.apollographql.com/docs/apollo-server/api/apollo-server/
|
138 |
|
139 | let graphQLServerOpts = {
|
140 | // typeDefs: Contains GraphQL type definitions in SDL or file
|
141 | // path to type definitions (required if schema is not provided *)
|
142 | // @url: https://www.prisma.io/blog/graphql-sdl-schema-definition-language-6755bcb9ce51
|
143 | typeDefs: undefined, // String | Function | DocumentNode or array of previous
|
144 |
|
145 | // resolvers: Contains resolvers for the fields specified in
|
146 | // typeDefs (required if schema is not provided *)
|
147 | resolvers: undefined, // Object
|
148 |
|
149 | // Object which controls the resolver validation behaviour for more information
|
150 | // @url: https://www.apollographql.com/docs/graphql-tools/generate-schema.html#makeExecutableSchema
|
151 | resolverValidationOptions: undefined,
|
152 |
|
153 | // Applies mocks to schema. Setting this to true will apply a default mock,
|
154 | // however you can pass an object to customize the mocks similar to the resolvers map.
|
155 | // @url: https://github.com/apollographql/graphql-tools/blob/master/docs/source/mocking.md
|
156 | mocks: undefined, // Object | Boolean
|
157 |
|
158 | // Contains custom data being passed through your resolver chain.
|
159 | // This can be passed in as an object, or as a Function with the
|
160 | // signature (req: ContextParameters) => any *
|
161 | // IMPORTANT: db is passed to the context, as an insance of the
|
162 | // waterline ORM.
|
163 | //
|
164 | // so e.g:
|
165 | // myResolver = async (_, args, ctx) => {
|
166 | // const UserModel = ctx.db.model("User");
|
167 | // return await UserModel.find();
|
168 | // }
|
169 | context: req => {
|
170 | return {
|
171 | ...req,
|
172 | aContextServiceProvoder
|
173 | };
|
174 | },
|
175 |
|
176 | // schemaDirectives: Apollo Server schema directives that allow for
|
177 | // transforming schema types, fields, and arguments
|
178 | // @url: https://www.apollographql.com/docs/graphql-tools/schema-directives.html
|
179 | schemaDirectives: undefined, // Object
|
180 |
|
181 | // middlewares: A list of GraphQLMiddleware middleware.
|
182 | // @url: https://github.com/prisma/graphql-middleware
|
183 | middlewares: [] // array of Middleware
|
184 | };
|
185 | ```
|
186 |
|
187 | The `props` argument accepts the following fields:
|
188 |
|
189 | | Key | Type | Default | Note |
|
190 | | --------------------------- | --------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
191 | | `typeDefs` | `String` or `Function` or `DocumentNode` or `array` of previous | `null` | Contains GraphQL type definitions in [SDL](https://blog.graph.cool/graphql-sdl-schema-definition-language-6755bcb9ce51) or file path to type definitions (required if `schema` is not provided \*) |
|
192 | | `resolvers` | Object | `null` | Contains resolvers for the fields specified in `typeDefs` (required if `schema` is not provided \*) |
|
193 | | `resolverValidationOptions` | Object | `null` | Object which controls the resolver validation behaviour (see ["Generating a schema"](https://www.apollographql.com/docs/graphql-tools/generate-schema.html#makeExecutableSchema)) for more information |
|
194 | | `schema` | Object | `null` | An instance of [`GraphQLSchema`](http://graphql.org/graphql-js/type/#graphqlschema) (required if `typeDefs` and `resolvers` are not provided \*) |
|
195 | | `mocks` | Object or Boolean | `null` | Applies [mocks to schema](https://github.com/apollographql/graphql-tools/blob/master/docs/source/mocking.md). Setting this to true will apply a default mock, however you can pass an object to customize the mocks similar to the resolvers map. |
|
196 | | `context` | Object or Function | `{}` | Contains custom data being passed through your resolver chain. This can be passed in as an object, or as a Function with the signature `(req: ContextParameters) => any` \*\* |
|
197 | | `schemaDirectives` | Object | `null` | [`Apollo Server schema directives`](https://www.apollographql.com/docs/graphql-tools/schema-directives.html) that allow for transforming schema types, fields, and arguments |
|
198 | | `middlewares` | `array` of Middleware | `[]` | A list of [`GraphQLMiddleware`](https://github.com/graphcool/graphql-middleware) middleware. |
|
199 |
|
200 | > (\*) **!! YET NOT SUPPORTED !!** , but when supported, there are two major ways of providing the [schema](https://blog.graph.cool/graphql-server-basics-the-schema-ac5e2950214e) information to the `constructor`:
|
201 | >
|
202 | > 1. Provide `typeDefs` and `resolvers` and omit the `schema`, in this case `@apollo-waterline/server` will construct the `GraphQLSchema` instance using [`buildFederatedSchema`](https://www.apollographql.com/docs/apollo-server/api/apollo-federation/) from [`@apollo/federation`](https://github.com/apollographql/apollo-server/tree/master/packages/apollo-federation).
|
203 | > 2. Provide the `schema` directly and omit `typeDefs` and `resolvers`. We recommend to use [`buildFederatedSchema`](https://www.apollographql.com/docs/apollo-server/api/apollo-federation/) to be able to use it in an API Gateway with Apollo Gateway
|
204 |
|
205 | > (\*\*) Notice that the `req` argument is an object of the shape `{ request, response, connection }` which either carries a `request: Request` property (when it's a `Query`/`Mutation` resolver), `response: Response` property (when it's a `Query`/`Mutation` resolver), or a `connection: SubscriptionOptions` property (when it's a `Subscription` resolver). [`Request`](http://expressjs.com/en/api.html#req) is imported from Express.js. [`Response`](http://expressjs.com/en/api.html#res) is imported from Express.js aswell. `SubscriptionOptions` is from the [`graphql-subscriptions`](https://github.com/apollographql/graphql-subscriptions) package. `SubscriptionOptions` are getting the `connectionParams` automatically injected under `SubscriptionOptions.context.[CONNECTION_PARAMETER_NAME]`
|
206 |
|
207 | ### bootOpts
|
208 |
|
209 | The `bootOpts` object has the following fields:
|
210 |
|
211 | | Key | Type | Default | Note |
|
212 | | ------------------------ | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
213 | | `cors` | Object | `null` | Contains [configuration options](https://github.com/expressjs/cors#configuration-options) for [cors](https://github.com/expressjs/cors) |
|
214 | | `tracing` | Boolean or [TracingOptions](/src/types.ts#L49-L51) | `'http-header'` | Indicates whether [Apollo Tracing](https://github.com/apollographql/apollo-tracing) should be enabled or disabled for your server (if a string is provided, accepted values are: `'enabled'`, `'disabled'`, `'http-header'`) |
|
215 | | `port` | Number or String | `4000` | Determines the port your server will be listening on (note that you can also specify the port by setting the `PORT` environment variable) |
|
216 | | `endpoint` | String | `'/'` | Defines the HTTP endpoint of your server |
|
217 | | `subscriptions` | Object or String or `false` | `'/'` | Defines the subscriptions (websocket) endpoint for your server; accepts an object with [subscription server options](https://github.com/apollographql/subscriptions-transport-ws#constructoroptions-socketoptions) `path`, `keepAlive`, `onConnect` and `onDisconnect`; setting to `false` disables subscriptions completely |
|
218 | | `playground` | String or `false` | `'/'` | Defines the endpoint where you can invoke the [Playground](https://github.com/graphcool/graphql-playground); setting to `false` disables the playground endpoint |
|
219 | | `defaultPlaygroundQuery` | String | `undefined` | Defines default query displayed in Playground. |
|
220 | | `uploads` | [UploadOptions](/src/types.ts#L39-L43) or `false` or `undefined` | `null` | Provides information about upload limits; the object can have any combination of the following three keys: `maxFieldSize`, `maxFileSize`, `maxFiles`; each of these have values of type Number; setting to `false` disables file uploading |
|
221 | | `https` | [HttpsOptions](/src/types.ts#L62-L65) or `undefined` | `undefined` | Enables HTTPS support with a key/cert |
|
222 | | `getEndpoint` | String or Boolean | `false` | Adds a graphql HTTP GET endpoint to your server (defaults to `endpoint` if `true`). Used for leveraging CDN level caching. |
|
223 | | `deduplicator` | Boolean | `true` | Enables [graphql-deduplicator](https://github.com/gajus/graphql-deduplicator). Once enabled sending the header `X-GraphQL-Deduplicate` will deduplicate the data. |
|
224 | | `bodyParserOptions` | BodyParserJSONOptions | [BodyParserJSONOptions Defaults](https://github.com/expressjs/body-parser#bodyparserjsonoptions) | Allows pass through of [body-parser options](https://github.com/expressjs/body-parser#bodyparserjsonoptions) |
|
225 |
|
226 | Additionally, the `options` object exposes these `apollo-server` options:
|
227 |
|
228 | | Key | Type | Note |
|
229 | | ----------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
230 | | `cacheControl` | Boolean | Enable extension that returns Cache Control data in the response |
|
231 | | `formatError` | Number | A function to apply to every error before sending the response to clients. See [API Reference: apollo-server
|
232 | ](https://www.apollographql.com/docs/apollo-server/api/apollo-server/#parameters). Please beware, that if you override this, `requestId` and `code` on errors won't automatically be propagated to your @apollo-waterline/server server |
|
233 | | `logFunction` | LogFunction | A function called for logging events such as execution times |
|
234 | | `rootValue` | any | RootValue passed to GraphQL execution |
|
235 | | `validationRules` | Array of functions | Additional GraphQL validation rules to be applied to client-specified queries |
|
236 | | `fieldResolver` | GraphQLFieldResolver | Specify a custom default field resolver function |
|
237 | | `formatParams` | Function | A function applied to each query in a batch to format parameters before execution |
|
238 | | `formatResponse` | Function | A function applied to each response after execution |
|
239 | | `debug` | boolean | Print additional debug logging if execution errors occur |
|