Multiple GraphQL Schemas with PostGraphile
Each PostGraphile instance only creates a single GraphQL schema ─ you don't get one schema per user based on permissions, for example. Typically, in GraphQL, a single schema is what you want ─ it allows you to use the various GraphQL tooling for autocomplete, linting, mapping, etc using the same shared schema.
However it sometimes makes sense to provide two or more different schemas; for example if you have two completely independent use-cases, or if you need to generate a special "admin" schema that only admins can access.
Typically it's a good idea to put different schemas on different URIs; it makes it easier to point to the relevant schema, download its description, and perform the relevant linting/etc with it. If someone is not allowed access to a schema they simply cannot access that endpoint.
It's possible to run multiple PostGraphile schemas in a single Node.js server,
either mounting them at different endpoints or on the same URI and use a simple
middleware to switch between them. The key thing is to not call postgraphile
more times then the number of services you have. So if you have two services you
want to only be calling postgraphile
twice and not once for every request.
(This is because every time postgraphile
is called, it will perform a fresh
introspection of your database schema and generate the GraphQL API from that -
this would cause considerable lag!)
Multiple endpoints
Here's an example of mounting multiple PostGraphiles at different endpoints:
const services = {
notification: "CONNECTION_STRING_TO_NOTIFICATION_SERVICE",
user: "CONNECTION_STRING_TO_USER_SERVICE",
};
for (const [service, connectionString] of Object.entries(services)) {
app.use(
postgraphile(connectionString, "public", {
graphiql: true,
graphqlRoute: `/${service}/graphql`,
graphiqlRoute: `/${service}/graphiql`,
}),
);
}
Single endpoint, multiple GraphQL schemas
Here's an example of switching which PostGraphile is used at a single endpoint based on some information provided in the HTTP request:
const services = {
notification: postgraphile(
"CONNECTION_STRING_TO_NOTIFICATION_SERVICE",
"public",
{
graphiql: true,
},
),
user: postgraphile("CONNECTION_STRING_TO_USER_SERVICE", "public", {
graphiql: true,
}),
};
app.use((req, res, next) => {
if (someCondition) {
services.notification(req, res, next);
} else {
services.user(req, res, next);
}
});
Code from the example by @calebmer in this issue: https://github.com/graphile/postgraphile/issues/427#issuecomment-293032341