Apollo Federation 2 Guide
This guide refers to Apollo Federation 2, if you’re looking for the 1.0 guide, please see the federation v1 guide.
Apollo Federation allows you to combine multiple GraphQL APIs into one. This can be extremely useful when working with a service oriented architecture.
Strawberry supports Apollo Federation 2 out of the box, that means that you can create services using Strawberry and federate them via Apollo Gateway or Apollo Router.
Federated schema example
Letβs look at an example on how to implement Apollo Federation using Strawberry. Let’s assume we have an application with two services that each expose a GraphQL API:
-
books
: a service to manage all the books we have -
reviews
: a service to manage book reviews
Our folder structure will look something like this:
This guide assumes you've installed strawberry in both the books and reviews service
Books service
Let's create the books
service, copy the following inside books/app.py
enable_federation_2=True
is used to enable Apollo Federation 2 and currently
defaults to False
. This will change in a future version of Strawberry.
We defined two types: Book
and Query
, where Query
has only one field that
allows us to fetch all the books.
Notice that the Book
type is using the strawberry.federation.type
decorator,
as opposed to the normal strawberry.type
, this new decorator extends the base
one and allows us to define federation-specific attributes on the type.
Here, we are telling the federation system that the Book
’s id
field is its
uniquely-identifying key.
Federation keys can be thought of as primary keys. They are used by the gateway to query types between multiple services and then join them into the augmented type.
Reviews service
Now, letβs take a look at our review service: we want to define a type for a
review but also extend the Book
type to have a list of reviews.
Copy the following inside reviews/app.py
:
Now things are looking more interesting; the Review
type is a GraphQL type
that holds the contents of the review.
But we also have a Book
which has 3 fields, id
, reviews_count
and
reviews
.
In Apollo Federation 1 we’d need to mark the Book
type as an extension and
also we’d need to mark id
as an external field, this is not the case in Apollo
Federation 2.
Finally, we also have a class method, resolve_reference
, that allows us to
instantiate types when they are referred to by other services. The
resolve_reference
method is called when a GraphQL operation references an
entity across multiple services. For example, when making this query:
resolve_reference
is called with the id
of the book for each book returned
by the books service. Recall that above we defined the id
field as the key
for the Book
type. In this example we are creating an instance of Book
with
the requested id
and a fixed number of reviews.
If we were to add more fields to Book
that were stored in a database, this
would be where we could perform queries for these fields’ values.
We also defined a Query
type that has a single field, _hi
, which returns a
string. This is required because the GraphQL spec mandates that a GraphQL server
defines a Query type, even if it ends up being empty/unused.
Finally we also need to let Strawberry know about our Book and Review types.
Since they are not reachable from the Query
field itself, Strawberry won’t be
able to find them.
If you don’t need any custom logic for your resolve_reference, you can omit it
and Strawberry will automatically instanciate the type for you. For example, if
we had a Book
type with only an id
field, Strawberry would be able to
instanciate it for us based on the data returned by the gateway.
Let's run our services
Before starting Apollo Router to compose our schemas we need to run the services.
In two terminal windows, run the following commands:
Apollo Router
Now we have our services up and running, we need to configure a gateway to consume our services. Apollo provides a router that can be used for this.
Before continuing we'll need to install Apollo Router by following their installation guide and we'll need to install Apollo's CLI to compose the schema.
Composing the schema means combining all our service's schemas into a single schema. The composed schema will be used by the router to route requests to the appropriate services.
Create a file called supergraph.yaml
with the following contents:
This file will be used by rover to compose the schema, which can be done with the following command:
Now that we have the composed schema, we can start the router.
Now that router is running we can go to http://localhost:4000 and try to run the following query:
if everything went well we should get the following result:
We have provided a full example that you can run and tweak to play with Strawberry and Federation. The repo is available here: https://github.com/strawberry-graphql/federation-demo
Federated schema directives
Strawberry provides implementations for Apollo federation-specific GraphQL directives up to federation spec v2.7.
Some of these directives may not be necessary to directly include in your code, and are accessed through other means.
-
@interfaceObject
(for more details, see Extending interfaces ) -
@key
(for more details, see Entities (Apollo Federation) ) -
@link
(is automatically be added to the schema when any other federated schema directive is used)
Other directives you may need to specifically include when relevant.
-
@composeDirective
-
@external
-
@inaccessible
-
@override
-
@provides
-
@requires
-
@shareable
-
@tag
-
@authenticated
-
@requiresScopes
-
@policy
For example, adding the following directives:
Will result in the following GraphQL schema: