Federated Graphs

A federated graph is a collection of subgraphs that are composed together to form a single graph. Each subgraph is a standalone GraphQL API that can be developed and deployed independently. The federated graph is the composition of these subgraphs into a single graph.

Create a new federated graph from a template with the following commands:

npx grafbase@latest init -t federated
npm install

The grafbase.config.ts file will now have the following content:

import { config, graph } from '@grafbase/sdk'

export default config({
  graph: graph.Federated(),
})

Now start the local development server by running the following command:

npx grafbase dev

This will start Pathfinder on http://127.0.0.1:4000 to explore and execute queries against the GraphQL endpoint at http://127.0.0.1:4000/graphql. A Schema Registry is also started to manage and compose subgraphs.

Initially the federated graph is empty, to add a new subgraph you need to publish it by running the following command:

npx grafbase publish --dev --name '<subgraph name>' --url '<graphql url>'

Using connectors you can add various data sources to subgraphs. For example, any API with a OpenAPI specification can be converted to a subgraph. Let's create a new project with the appropriate template:

npx grafbase@latest init -t openapi-subgraph
npm install

Configure the SCHEMA_URL in the .env file with the desired OpenAPI spec url. Now, start the server and publish the subgraph by running the following commands:

npx grafbase dev --port 4001
npx grafbase publish --dev --name openai --url http://localhost:4001/graphql

You should see your federated graph being updated in real time at http://127.0.0.1:4000!

By default, subgraphs will not get any headers forwarded from client requests. This needs to be configured explicitly in the federated graph configuration:

import { config, graph } from '@grafbase/sdk'

const g = graph.Federated({
  headers: headers => {
    // Sent to all subgraphs
    headers.set('User-Agent', 'Grafbase Federated Graph')
    // Forwarding a client header
    headers.set('Cookie', { forward: 'Cookie' })

    // Sent to specific subgraphs
    headers
      .subgraph('product')
      // environment variable in the .env file
      .set('Authorization', `Bearer: ${process.env.PRODUCT_API_KEY}`)
      .set('Referer', { forward: 'Referer' })
  },
})

export default config({
  graph: g,
})

Before executing any request, it is also possible to validate whether a user has access to the federated graph. By default, everything is public, but it can also be configured to use JWT authorization.

By default, any subgraph subscription requests will be made using the GraphQL over websockets protocol, against the same URL as normal HTTP subgraph calls.

This URL can be configured if needed:

import { config, graph } from '@grafbase/sdk'

const g = graph.Federated({
  subscriptions: subscriptions => {
    subscriptions
      .subgraph('Product')
      .transport(SubscriptionTransport.GraphQlOverWebsockets, {
        url: 'wss://example.com',
      })
  },
})

export default config({
  graph: g,
})

Eventually this will be updated to also support other transports. If you need support for another transport please reach out on Discord.

Was this page helpful?