- Enable Federation in Graphweaver
- Graphweaver Configuration
- Directives
- @Key
- @extends
- @external
- @provides
- @requires
- Federation Namespacing
- Examples
Graphweaver supports GraphQL Federation v1 and v2. GraphQL federation allows you to combine multiple GraphQL APIs (called subgraphs) into a single unified graph. This means you can have different teams or services manage their own GraphQL APIs independently and still provide a seamless experience for clients who only need to interact with the single federated graph.
Enable Federation in Graphweaver
There are a few important steps you will need to follow to enable federation on Graphweaver.
Graphweaver Configuration
There are two configuration options for Federation in Graphweaver.
federationSubgraphName
- Setting this to your team name will enable the additional Federation directives and queries in your API, as well as namespacing all singleton types we use so they won’t clash with other Graphweaver instances behind the same federation router.enableFederationTracing
- This enables the ability to trace requests through the federation.
enableFederationTracing
, any client can request a trace for any operation, potentially revealing sensitive server information. It is recommended to ensure that federated subgraphs are not directly exposed to the public Internet. This feature is disabled by default for security reasons.Here is how you configure these settings in your app:
export const graphweaver = new Graphweaver({
federationSubgraphName: 'music',
enableFederationTracing: true,
});
Once federationSubgraphName
is set to a string the Graphweaver server will add the following Federation queries to the server:
_service
- support for therover subgraph introspect
command (this is the Federation equivalent of Introspection for subgraphs)-
_entities
- query to fetch entity data - Below is an example of the single
@key
query that is sent from the graph router to the implementingproducts
subgraph:
query {
_entities(representations: [{ "__typename": "User", "email": "support@apollographql.com" }]) {
...on User { email name }
}
}
}
Directives
All federation directives are supported by Graphweaver.
- @key
- @requires
- @provides
- @link
- @shareable
- @tag
- @override
- @inaccessible
- @composeDirective
- @interfaceObject
The directives can be added inside the configuration of either the @Field
, @RelationshipField
or @Entity
decorators.
Let’s look at a few examples.
@Key
- GraphQL Federation: Identifies the fields that uniquely define an entity within a subgraph.
primaryKeyField: true
: In Graphweaver, you can mark a field as the primary key using this option on the@Field
decorator. This serves the same purpose as the@key
directive, identifying the entity's unique identifier.
@Field(() => ID, { primaryKeyField: true })
id!: string;
@extends
- GraphQL Federation: Indicates that an entity type is extended from another subgraph.
- Graphweaver: Allows you to add this directive inside the entity configuration:
@Entity('User', {
provider: new JsonDataProvider('User Management System'),
directives: {
extends: true,
},
})
@external
- GraphQL Federation: Marks a field as belonging to another subgraph, indicating that it cannot be resolved by the current subgraph.
- Graphweaver: The
@RelationshipField
and@Field
decorators allow you to add the@external
directive.
@Field(() => ID, { primaryKeyField: true, directives: { external: true } })
email!: string;
@provides
- GraphQL Federation: Specifies additional fields that should be fetched from the base type when a particular field is requested.
- Graphweaver: You can add this using the
directives
option within the@RelationshipField
or@Field
decorator:
@RelationshipField(() => User, {
id: 'createdBy',
directives: { provides: { fields: 'totalProductsCreated' } },
})
createdBy!: User;
@requires
- GraphQL Federation: Indicates that a field requires certain fields from another subgraph to be resolved.
- Graphweaver: You can add this using the
directives
option within the@Field
decorator
@Field(() => GraphQLInt, {
nullable: true,
directives: { requires: { fields: 'totalProductsCreated yearsOfEmployment' } },
})
averageProductsCreatedPerYear?: number;
Federation Namespacing
We have types in Graphweaver that are emitted once, and whose names are not controlled by developers. Because federated routers like Cosmo and Apollo use type names as the unique identifier for types, we need to namespace them, or you couldn’t have two or more Graphweaver instances behind a federated router. Our singleton types like Media
and AggregationResult
would clash. When you enable federation, you pass a subgraph name, like so:
const graphweaver = new Graphweaver({
federationSubgraphName: 'myTeam'
});
This will enable federation and also rename all of these singleton types. For example:
Media
⇒MediaFromMyTeamSubgraph
AggregationResult
⇒AggregationResultFromMyTeamSubgraph
This behaviour happens on an entity when you use apiOptions.namespaceForFederation
in the @Entity
decorator, like so:
@Entity('Media', {
apiOptions: {
namespaceForFederation: true,
},
})
export class Media {
// ... etc
}
So, if you want the namespacing behaviour, then set that option in the decorator, otherwise we’ll leave your entity names alone.
Examples
For a complete working example please see this Github project https://github.com/exogee-technology/graphweaver/tree/main/src/examples/federation.
For more information on the directives and their purpose see https://www.apollographql.com/docs/federation/federated-types/federated-directives/.