Custom relay compiler which supports persisted queries
Relay modern is awesome. However it's missing a few things, one of which is persisted queries. This package is a custom relay compiler which supports:
- persisted queries
- direct compilation of graphql-js
Direct graphql-js support means you can generate your relay queries, schema.graphql and query map files all in a single step!
yarn add relay-compiler-plus
Make sure you have the latest version of graphql-js:
yarn upgrade graphql --latest
-
Add this npm command to your package.json:
"scripts": { "rcp": "NODE_ENV=production relay-compiler-plus --schema <SCHEMA_FILE_PATH> --src <SRC_DIR_PATH>" },
where
<SCHEMA_FILE_PATH>
is the path to your schema.graphql or schema.json file or schema.js (yes! rcp now supports direct compilation from graphql-js!).<SRC_DIR_PATH>
is the path to your src directory
then:
npm run rcp
this should generate:
- query files (*.graphql.js) containing query ids and null query text. Note that if you omit NODE_ENV=production, rcp will include both the query id and the query text in your query files. This can be useful for debugging in development.
- A
queryMap.json
file under<SRC_DIR_PATH>/queryMap.json
. This file can be consumed by the server to map the query ids to actual queries. - If you specified a schema.js file, this will also generate a
schema.graphql
file under../<SRC_DIR_PATH>/schema.graphql
. Theschema.graphql
has to sit outside the src folder otherwise the relay-compiler will complain.
If your graphql-js file is complex and you need to override the default webpack config you can do so like this:
"scripts": { "rcp": "NODE_ENV=production relay-compiler-plus --webpackConfig <WEBPACK_CONFIG_PATH> --src <SRC_DIR_PATH>" },
where
<WEBPACK_CONFIG_PATH>
is the path to your custom webpack config to transpile your graphql-js schema. In your custom webpack config, you need to setoutput.libraryTarget: 'commonjs2'
. See the example config for a working copy.
-
On the server, use
matchQueryMiddleware
prior toexpress-graphql
to match queryIds to actual queries. Note thatqueryMap.json
is auto-generated by relay-compiler-plus at step 1.import Express from 'express'; import expressGraphl from 'express-graphql'; import {matchQueryMiddleware} from 'relay-compiler-plus'; // do this import queryMapJson from '../queryMap.json'; // do this const app = Express(); app.use('/graphql', matchQueryMiddleware(queryMapJson), // do this expressGraphl({ schema: graphqlSchema, graphiql: true, }));
-
On the client, modify your relay network fetch implementation to pass a
queryId
parameter in the request body instead of aquery
parameter. Note thatoperation.id
is generated byrelay-compiler-plus
in step 1.function fetchQuery(operation, variables) { return fetch('/graphql', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ queryId: operation.id, // do this variables, }), }).then(response => { return response.json(); }); }
Run your app and that's it!
Check the example for a fully working demo.