graphql2rest
Version:
GraphQL to REST converter: automatically generate a RESTful API from your existing GraphQL API
138 lines (84 loc) • 5.51 kB
Markdown
## Generating the REST API with init()
After `generateGqlQueryFiles()` is executed once, `init()` can be executed to create REST routes at runtime.
In this example, we'll use [Apollo Link](https://www.apollographql.com/docs/link/links/http/) to connect via HTTP to our GraphQL server which runs on `localhost` (however this could be any type GraphQL server, running locally or remote.)
Using Apollo Link with `fetch` is the simplest way to connect GraphQL2REST to an existing GraphQL server.
#### For example:
```js
const path = require('path');
const { schema } = require('./myGraphQLSchema.js'); // a GraphQLSchema object
const GraphQL2REST = require('graphql2rest');
const { execute, makePromise } = require('apollo-link');
const { createHttpLink } = require('apollo-link-http');
const fetch = require('node-fetch');
const express = require('express');
const app = express();
const gqlServerUri = 'http://localhost:3000/api/graphql'; // our existing GraphQL server
const link = createHttpLink({ uri: gqlServerUri, fetch });
/* GraphQL2REST execute function using apollo-link. Invokes GraphQL operation against gqlServerUri via node-fetch */
const executeGqlLink = (operation) => {
return makePromise(execute(link, operation));
};
const GQL_FILES_FOLDER = path.resolve(__dirname,'./gqlFilesFolder'); // folder previously generated by generateGqlQueryFiles()
const gql2restOptions = {
apiPrefix: '/api', //sets the API base path url
manifestFile: path.resolve(__dirname,'./api-manifest.json'), //pathname of manifest file. Default is ./manifest.json
gqlGeneratorOutputFolder: GQL_FILES_FOLDER //.gql files folder
};
const restRouter = GraphQL2REST.init(schema, executeGqlLink, gql2restOptions);
// restRouter now has our REST API attached
app.use('/', restRouter);
```
<br>
Now the following REST API is mounted and active (based on the [manifest file described earlier](manifest-example.json)):
> GET /api/users
> GET /api/users/{userId}
> POST /api/users
> PATCH /api/users/{userId}
> DELETE /api/users/{userId}
<br>
### The init() function
`init()` takes two mandatory parameters: your GraphQL **schema** and the GraphQL server ***execute function*** (whatever your specific GraphQL server implementation provides, or an Apollo Link function).
```ts
GraphQL2REST.init(
schema: GraphQLSchema,
executeFn: Function,
options?: Object,
formatErrorFn?: Function,
formatDataFn?: Function,
expressRouter?: Function)
```
`schema` is a GraphQLSchema object. You can generate this object using `buildSchema()` function from the `graphql` package.
`executeFn` is a function that, similarly to Apollo Link, accepts a single object with `{ query, variables, context, operationName }` arguments.
If you want to use another kind of GraphQL execution function, which receives different arguments, you can wrap that GraphQL 'execute' function with `executeFn`, and map the arguments so that the final execution function receives the right arguments and values (see the example under */examples*).
<br>
`options` can be used to define specific settings (see below). If undefined, default values will be used.
`formatErrorFn` is an optional function to custom format GraphQL error responses. It receives `(response, statusCode)` arguments where `response` is the original response from GraphQL and `statusCode` is the final HTTP status code. It should return the formatted response, to be sent by REST API to the user.
`formatDataFn` is an optional function to custom format non-error GraphQL responses (data). It receives a `response` argument which is the original response from GraphQL.
If not provided, default behavior is to strip the encapsulating `'data:'` property and operation name, and omit the `'errors'` array from successful responses.
`expressRouter` is an express.Router() instance to attach new routes to (if not provided, a new Express instance will be returned).
<br>
#### The options object:
For any fields not specified in the *options* object, or if *options* is not provided to init(), values from the *defaults.json* file will be used.
These are all optional settings that can be defined in `options`:
```js
const gql2restOptions = {
apiPrefix: '/api/v2', //sets the API base path url
manifestFile: './api-v2-manifest.json', //pathname of manifest file
gqlGeneratorOutputFolder: './gqls', //.gql files folder (generated by generateGqlQueryFiles())
middlewaresFile: './middlewares.js', //optional middlewares module for modifying requests
filterFieldName: 'fields', //global query parameter name for filtering (default is 'fields')
graphqlErrorCodeObjPath: 'errors[0].extensions.code', //property name for GraphQL error code for error mapping
logger: myCustomLogger //optional Winston-based logger function
};
const expressRouter = GraphQL2REST.init(schema, execute, gql2restOptions);
```
Use ``path.resolve(__dirname, <PATH>)`` for relative paths.
All fields in `options` are optional, but init() will not be able to run without a valid manifest file and gqlGeneratorOutputFolder previously populated by `generateGqlQueryFiles()`.
<br>
---
Learn more about:
- [Filtering and shaping the responses on the client side](Client%20filters.md)
- [Customizing and formatting response format](Formatting%20responses.md)
- [Using apollo-link to work with a remote GraphQL server](Using%20remote%20GraphQL%20server.md)
<br>
[Back to [the tutorial](https://github.com/sisense/graphql2rest#tutorial)]