简体   繁体   中英

Relay app: How to introspect schema on server?

I'm playing with relay-starter-kit. I've also used sangria to create a graphql server. Now I'm trying to wire the two together.

In relay-starter-kit, every time you alter the schema, you need to run a script to regenerate the schema.json file. But since graphql supports schema introspection I'm wondering if there's a way to configure my relay app to introspect the schema from the server when it starts up.

Does anyone know if this is possible or worked out how to do this?

Define a babelRelayPlugin.js (which is run by webpack when validating the client graphql queries) as such:

var babelRelayPlugin   = require('babel-relay-plugin');
var introspectionQuery = require('graphql/utilities').introspectionQuery;
var request            = require('sync-request');

var url = 'http://localhost:3000/graphql';

var response = request('POST', url, {
   qs: {
      query: introspectionQuery
   }
});

var schema = JSON.parse(response.body.toString('utf-8'));

module.exports = babelRelayPlugin(schema.data, {
   abortOnError: true,
});

Of course, change the url variable to whatever server url you use for development. In webpack, include the following in your loaders definition:

query: {stage: 0, plugins: ['./babelRelayPlugin']}

and point to the location of the above babelRelayPlugin.js file.

Looks like we need something like this (from https://github.com/facebook/relay/blob/master/scripts/jest/updateSchema.js#L25 ):

import { buildASTSchema, introspectionQuery } from 'graphql/utilities';

var body = fs.readFileSync(inFile, 'utf8');
var ast = parseSchemaIntoAST(body);
var astSchema = buildASTSchema(ast, 'Root', 'Mutation');
graphql(astSchema, introspectionQuery).then(
    function(result) {
      var out = JSON.stringify(result, null, 2);
      fs.writeFileSync(outFile, out);
});

The introspection product (schema.json) is used by the Babel Relay Plugin to validate and compile Relay.QL expressions. Luckily, the getBabelRelayPlugin method accepts either an introspection product, or a function that returns an introspection product.

It should be possible then to do something like this in your app's build system (eg. Webpack):

// Pseudocode
var SCHEMA_PATH = 'path/to/schema.js';
var introspectionProduct = introspectSchema(SCHEMA_PATH);

watch(SCHEMA_PATH, () => introspectionProduct = introspectSchema(SCHEMA_PATH));

var babelRelayPlugin = getBabelRelayPlugin(() => introspectionProduct);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM