What is Apollo Federation, and which open-source projects can be a subgraph?

Apollo Federation composes several GraphQL services, called subgraphs, into one supergraph that a router serves; a subgraph declares which of its types are entities with @key and resolves them by key through the _entities field. For PostgreSQL, the options that work as a subgraph Apollo Router can call include Postrust (open source, Federation v2, generated from the schema), Hasura v2 (Federation v1) and Hasura DDN, while PostGraphile, GraphJin, Grafbase's Postgres extension and pg_graphql fall short in different ways.

What is Apollo Federation?

Apollo Federation is a way to build one GraphQL API out of several independent GraphQL services. Each service, a subgraph, owns part of the schema; their schemas are composed into a supergraph, and a router such as Apollo Router serves it, splitting each client query into requests to the subgraphs that own the fields asked for.

What ties the subgraphs together is the entity: an object type that more than one subgraph can contribute fields to, identified by the fields named in its @key directive. A catalog service and a reviews service can both define Product @key(fields: "id"), each with its own fields, and the router joins them by id. Composition — done with Rover’s rover supergraph compose, or by Apollo GraphOS — checks that the subgraph schemas fit together before anything is served.

Which open-source projects can serve PostgreSQL as a subgraph?

Among tools that generate GraphQL from PostgreSQL, few are a working subgraph Apollo Router can call. Where each stood in October 2026, from its own documentation:

ToolAs a Federation subgraph, October 2026
PostrustA Federation v2 subgraph, generated from the schema. Turned on with PGRST_GRAPHQL_FEDERATION=true; primary keys become @key and _entities resolves them. Apollo's compatibility suite runs in its CI, but it is not on Apollo's list of compatible subgraphs. Docs
Hasura v2A subgraph, Federation v1 only. Turned on with HASURA_GRAPHQL_ENABLE_APOLLO_FEDERATION, then table by table with apollo_federation_config in metadata. Source
Hasura DDN (v3)Documented as compliant with the subgraph specification, configured per object type and model. The docs name no Federation version, and other subgraphs cannot extend DDN's types. Source
IBM API Connect for GraphQL (formerly StepZen)On Apollo's list of compatible subgraphs; PostgreSQL through @dbquery. Commercial, as SaaS or self-hosted software. Source
PostGraphile@graphile/federation for v4 is a proof of concept, last published in 2021 and unmaintained. Nothing equivalent was found for V5. Source
GraphJinServes Federation 2 SDL, but _entities is not implemented yet, so it composes and cannot resolve an entity another subgraph references. Source
Grafbase Postgres extensionRuns inside Grafbase Gateway as a virtual subgraph; there is no server for Apollo Router to call. Source
Supabase pg_graphqlNo Federation support; its maintainers have said it is not planned. Source

The differences that matter are in the details: Hasura v2 speaks only Federation v1, GraphJin composes but cannot resolve entities, PostGraphile’s plugin is unmaintained, and Grafbase’s extension needs Grafbase Gateway rather than Apollo Router. Postrust is the project this site is about, so read its row with that in mind.

What does a service have to implement to be a subgraph?

Two fields beyond its own schema, plus the Federation directives in its SDL.

  • _service { sdl } returns the subgraph’s schema, with Federation directives, for composition.
  • _entities(representations: [...]) takes a list of keys — { __typename: "Product", id: 1 } — and returns those objects in the same order, so the router can fetch this subgraph’s fields for objects another subgraph found.

Apollo publishes a subgraph compatibility suite that tests these against a reference schema, separating required behaviour from optional features, and keeps a list of compatible subgraph libraries.

How do Federation v1 and v2 differ?

Federation v2 changed how subgraphs share types, and the two versions are not interchangeable at the subgraph level. In v1, a subgraph that added fields to another’s entity wrote it as extend type and marked the borrowed key fields @external. In v2, every subgraph defines the entity as an ordinary type with @key, a field that more than one subgraph may resolve must be marked @shareable, and directives such as @override, @inaccessible and @interfaceObject were added. Which version a tool speaks matters: it decides which of these a subgraph can express.

Why generate a subgraph from the database?

Because for tables, a hand-written subgraph is mostly a transcription of the catalog. A resolver for every field and an entity resolver for every type restate what PostgreSQL already knows: a table is a type, a primary key is an @key, a foreign key is a relationship, and _entities is a WHERE key IN (...).

Generating that is the easy part. To be a real subgraph, a generated schema also has to:

  • resolve _entities, not just print Federation SDL — a subgraph that composes but cannot resolve a reference is what GraphJin is today;
  • resolve many keys at once rather than one query per key, and return null in place for a key that matches nothing;
  • let two databases agree that a table is the same entity, which the catalog cannot say on its own;
  • keep generated names from colliding when several subgraphs from similar schemas are composed;
  • apply the same access rules to entity lookups as to any other read.

How do you turn on Federation in Postrust?

Set PGRST_GRAPHQL_FEDERATION=true. The GraphQL API at /v1/graphql then gains _service, _entities and the Federation v2 directives, and its root types are named Query, Mutation and Subscription. With it unset, the schema is unchanged.

a subgraph over one database
PGRST_GRAPHQL_FEDERATION=true
PGRST_GRAPHQL_TYPE_PREFIX=catalog            # optional: avoid name collisions
PGRST_GRAPHQL_METADATA=/config/metadata.json # optional: shared entities, names

Every readable table with a primary key becomes an entity keyed by it. When another subgraph contributes to the same entity, mark the table shared in the metadata: it keeps its unprefixed type name, and its non-key fields are marked @shareable.

metadata.json
{
  "tables": {
    "public.products": {
      "name": "Product",
      "federation": { "shared": true }
    }
  }
}

Each type’s representations are resolved in one query, keys are checked against the key column’s type before anything reaches the database, and an unknown key is a null in its position. Postrust runs Apollo’s compatibility suite in CI on changes to its GraphQL code and the required checks must pass; the Federation documentation lists what is not supported yet, such as @requires, @provides and keys other than the primary key.

How do authentication and row-level security pass through the router?

The router forwards the caller’s token, and each subgraph enforces it. The router has to pass the token on rather than stop at it, so propagate the Authorization header:

router.yaml
headers:
  all:
    request:
      - propagate:
          named: authorization

Each Postrust subgraph verifies the JWT itself and runs its part of the query — _entities included — as the role the token names, or the anonymous role without one. PostgreSQL’s row-level security policies then decide which rows come back; nothing in the router filters anything. A token that does not verify is refused as invalid-jwt rather than answered as anonymous. Each subgraph can have its own roles and policies; the token is the only thing they share.

Where is a complete worked example?

PostgreSQL as an Apollo Federation subgraph walks through two databases, a Postrust subgraph over each, Rover and Apollo Router, with queries in both directions and a policy that shows editors unpublished reviews. It runs as examples/federation, whose check.sh also runs in Postrust’s CI. For Postrust against these tools more broadly, see Postrust vs Hasura and Postrust vs PostGraphile.

Questions people ask: Apollo Federation and Open-Source Subgraphs

What is a subgraph in Apollo Federation?

A subgraph is one GraphQL service in a federated graph. Beyond its own schema it answers _service, which returns its SDL for composition, and _entities, which returns objects by key so the router can fetch fields this service owns for objects another service found.

What does the @key directive do?

@key marks an object type as an entity and names the fields that identify it, such as @key(fields: "id"). The router uses those fields to ask any subgraph that contributes to the entity for its part of the object.

Can PostgreSQL be an Apollo Federation subgraph without writing resolvers?

Yes, with a server that generates the subgraph from the schema. Postrust does this: each table with a primary key becomes an entity keyed by that primary key, and _entities runs one query per type for all the keys the router sends.

Does row-level security still apply behind Apollo Router?

With Postrust, yes, as long as the router passes the Authorization header on to the subgraphs. Each subgraph verifies the token and runs its part of the query, _entities included, as the role the token names, so PostgreSQL's policies decide what each caller sees.

Which Federation directives does Postrust not support?

Keys other than the primary key, @requires, @provides, @external, @override, @tag, @inaccessible, @composeDirective, @interfaceObject and federated tracing. These are optional in Apollo's subgraph compatibility suite; the required checks pass in Postrust's CI.

Is Hasura an Apollo Federation v2 subgraph?

Hasura v2 supports Federation v1 only, enabled with HASURA_GRAPHQL_ENABLE_APOLLO_FEDERATION and per-table metadata. Hasura DDN is documented as compliant with the subgraph specification but its docs name no Federation version, as of October 2026.