Working with Federation
Apollo Connectors simplify GraphQL federation
Under the hood, Apollo Connectors are Apollo Federation. Instead of resolving fields by calling a GraphQL subgraph, connectors enable federation to resolve fields from other kinds of APIs like REST.
This means that connectors work seamlessly with multiple subgraphs composed together into a supergraph. You can use connectors to extend and reference entities from other subgraphs.
Extend entities
Connectors let you augment entities in your supergraph with data from REST APIs.
Suppose your supergraph already has a products
subgraph that provides the id
, name
, and price
of a Product
entity:
1type Product @key(fields: "id") {
2 id: ID!
3 name: String
4 price: Int
5}
@key
is what makes Product
an entity. Learn more about entities and about the rules for entities in connectors.You can add product review data from a REST API using the @connect
directive like so:
1type Product @key(fields: "id") {
2 id: ID!
3 reviews: [Review]
4 @connect(
5 http: { GET: "https://reviews.example.com/reviews?product_id={$this.id}" }
6 selection: """
7 $.results {
8 id
9 title
10 body
11 rating
12 }
13 """
14 )
15}
16
17type Review {
18 id: ID!
19 title: String
20 body: String
21 rating: Int
22}
The @connect
directive defines the reviews
fields to request from the /reviews
endpoint.
The id
used as a parameter in the endpoint URL comes from the product's id
field, which comes from another subgraph.
Reference entities
If your REST API provides foreign key references, you can use them to reference entities and fetch corresponding fields from a different subgraph.
For example, if your REST API lets you fetch a user's favorite products and provides those products' IDs, you can use the @connect
directive to reference the Product
entity:
1type User @key(fields: "id") {
2 id: ID!
3 favoriteProducts: [Product]
4 @connect(
5 http: { GET: "https://products.example.com/users/{$this.id}/favorites" }
6 selection: """
7 $.results {
8 id: product_id
9 }
10 """
11 )
12}
13
14type Product @key(fields: "id", resolvable: false) {
15 id: ID!
16}
Add a computed field using @requires
1type Product @key(fields: "id") {
2 id: ID!
3 weight: Int @external
4 shippingCost(zipCode: String): Int
5 @requires(fields: "weight")
6 @connect(
7 http: {
8 GET: "https://api.example.com/shipping?zip={$args.zipCode}&weight={$this.weight}"
9 }
10 selection: "$.result"
11 )
12}
Compatibility with other Federation features
Connectors work seamlessly with most other Federation features. You can use directives like @tag
, @inaccessible
, @provides
, and more alongside @connect
.