Subgraphs
You've got documents. You've got operations. Now you need the outside world — a web app, a mobile client, an AI agent — to be able to read and write that data over the network. That's exactly what a does.
One endpoint, many packages
Switchboard doesn't expose a single monolithic schema. Instead, every Reactor Package ships its own GraphQL schema fragment — its subgraph. When Switchboard boots, it composes all of those fragments into one unified endpoint.
The practical payoff: a client can query data from two completely independent packages in a single request. Neither package knows about the other. Switchboard handles the stitching.
query {
todoList(id: "doc-123") {
id
todos {
id
title
done
}
}
}
That query hits one endpoint. Behind the scenes, it's resolved by whatever package owns the todoList type.
Subgraphs are the API face of your document model
If a document model defines the shape of your data and the actions allowed on it, the subgraph is how that shape appears to callers on the network.
Each subgraph exposes three things:
- Queries — for reading documents and processor read models.
- Mutations — for dispatching actions to documents.
- Custom types — domain-specific GraphQL types your resolvers return.
Because each package owns its subgraph, the package is the unit of delivery. Ship a new package and its API comes with it — no central schema registry to update.
Where mutations go
A mutation in a subgraph isn't stored as a database write. It dispatches an action to the underlying document via the Reactor.
Mutation: {
async addTodo(_parent, { input }, ctx) {
return ctx.reactor.dispatch("<doc-id>", [
{ type: "ADD_TODO", input }
]);
}
}
The Reactor runs the action through the reducer, stamps it as an operation, appends it to the document history, and syncs it to connected peers. The subgraph layer is thin — it translates network calls into document actions and hands off.