Custom relay compiler which supports persisted queries
Custom relay compiler which supports persisted queries :bowtie:
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:
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 directorythen:
npm run rcp
this should generate:
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.schema.graphql
file under ../<SRC_DIR_PATH>/schema.graphql
. The schema.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 set output.libraryTarget: 'commonjs2'
. See the example config
for a working copy.On the server, use matchQueryMiddleware
prior to express-graphql
to match queryIds to actual queries. Note
that queryMap.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 a query
parameter. Note that operation.id
is generated by relay-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.