Bundle `graphql-voyager` in GraphiQL
I'm submitting a ...
- [ ] bug report
- [x] feature request
- [ ] question
It is fairly trivial to expose graphql-voyager yourself if you are already consuming postgraphile as a library. Doing so is roughly as easy as:
import * as express from 'express';
import { express as voyagerMiddleware } from 'graphql-voyager/middleware';
import { postgraphile } from 'postgraphile';
const app = express();
app.use(postgraphile(PG_POOL, PG_SCHEMA, graphileConfig));
app.use('/voyager', voyagerMiddleware({
endpointUrl: `${graphileConfig.externalUrlBase || ''}/graphql`,
displayOptions: {
hideRoot: true,
skipDeprecated: true,
skipRelay: true,
},
}));
app.listen(PORT, () => {
console.log(`Listening on localhost:${PORT}`);
});
It would be nice to have Voyager bundled for a couple reasons, namely:
- easier for CLI users to explore their schema graphically
- possibility for tighter integration with our custom GraphiQL interface (i.e. deep linking, which is not yet supported by Voyager)
- could be loaded at the same
/graphiqlendpoint
Related to #1074 in that Voyager is probably closer to what you'd want to expose to end-users instead of the entire GraphiQL console.
I definitely don't want to bundle more stuff inside PostGraphile; however I've planned to write a voyager server plugin for quite a while just haven't got around to it. To do so, you should only need to implement one hook, against this:
https://github.com/graphile/postgraphile/blob/83024fbba8f20b123bcec6b5f3543f0500bfd011/src/postgraphile/http/createPostGraphileHttpRequestHandler.ts#L435-L446
Something like:
const { express: makeVoyagerMiddleware } = require('graphql-voyager/middleware');
let voyagerMiddleware;
module.exports = {
// Use this hook for access to the options, so we know where the GraphQL endpoint is:
'postgraphile:options': (options) => {
voyagerMiddleware = makeVoyagerMiddleware({
endpointUrl: `${options.externalUrlBase || ''}/${options.graphqlRoute}`,
displayOptions: {
hideRoot: true,
skipDeprecated: true,
skipRelay: true,
},
});
return options;
},
// Use this hook to pass over to the voyager middleware if the request matches
'postgraphile:http:handler': (incomingReq, { options, res, next }) => {
if (!incomingReq.match(/^\/voyager(\?|$)/)) return incomingReq;
middleware(incomingReq, res, next);
return null;
}
};
This was written direct into GitHub editor, so it's probably going to need some fixes.