mesh-local-federation
v2.1.1
Published
Graphql-mesh helper to run federated gateway with local executable graphql schema
Downloads
598
Readme
GraphQL mesh gateway with local federation
Disclaimer: This is 100% glue around the the following excellent packages:
... But for this specific workflow it sets things up in a simple and clean way and removes un-needed boilerplate.
The package exposes only 2 functions:
createSupergraph
- Takes external services and the local schema to produce the supergraph definitioncreateMeshInstance
- Takes the supergraph definition from createSupergraph and local schema to build a executable gateway configuration that can be used with graphql-yoga
Workflow
graph LR;
subgraph Instance
gateway(Graphql\ngateway):::local--context-->local(Local executable schema):::local
db{{Supergraph\ndefinition}}:::data<-.load.->gateway
end
gateway--headers--->federated1(External service);
gateway--headers--->federated2(External service);
classDef local fill:#00b54f
Define external services
import type { SubgraphService } from "mesh-local-federation";
const subgraphs: SubgraphService[] = [
{
subgraphName: "users",
endpoint: "https://federated.users.service.endpoint/graphql",
},
{
subgraphName: "orders",
endpoint: "https://federated.orders.service.endpoint/graphql",
},
// ...
];
Create local executable schema
import { buildSubgraphSchema } from "@graphql-tools/federation";
import { createYoga } from "graphql-yoga";
const schema = buildSubgraphSchema({
typeDefs: /* GraphQL */ `
type Query {
hello: String
}
`,
resolvers: {
Query: {
hello: (obj, args, context, info) => {
// Full yoga server context is passed to the local subgraph
// See server creation in the last paragraph
return "world";
},
},
},
});
export const localSchema = createYoga({ schema });
Build supergraph definition
import { createSupergraph } from "mesh-local-federation";
const supergraphSDL = await createSupergraph({
subgraphs,
localSchema,
onRemoteRequestHeaders: ({ endpoint }) => {
return {
Authorization: `Bearer ${await getToken(endpoint)}`,
};
},
});
Result of this step can be cached and the resulting schema definition can be used for the next steps to speed up the precess significantly.
materialize-ts-function is a simple way to do this during build process.
Create server
import { createServer } from "node:http";
import { createMeshInstance } from "mesh-local-federation";
import { createYoga } from "graphql-yoga";
const config = await createMeshInstance({
supergraphSDL,
localSchema: localSchema,
onRemoteRequestHeaders: ({ endpoint }) => {
return {
Authorization: `Bearer ${await getToken(endpoint)}`,
};
},
});
const yoga = createYoga({
...config,
context: ({ request }) => {
// context will be available in onRemoteRequestHeaders
// and will be passed to local graph
},
});
const server = createServer(yoga);
server.listen(4000, () => {
console.info("Server is running on http://localhost:4000/graphql");
});
Thats it ...
... happy coding :)