I have recently learned about Federated Subgraphs and I think I can help you. All of my information comes from the courses they have here (https://www.apollographql.com/tutorials/). If you take a look at the Voyage 1 course, you can learn about entities in detail.
Since you want MenuItems
to be resolved by the Menu
subgraph through the Orders
subgraph, I'm assuming that data-wise an Order
would have an ID for a MenuItem
. You wouldn't need the @provides
or @external
directives in this case. What you could do, is this:
In your Order subgraph
- Start by declaring a
MenuItem
entity in your Order
subgraph.
type Order @key(fields: "id") {
id: ID!
item: MenuItem! // MenuItem type exists in the Menu subgraph
}
type MenuItem @key(fields: "id", resolvable: false) {
id: ID!
}
- Next, we move onto your
Order
resolver. For this example, since you didnt outline, I'll just say you have an orderById
function you use to fetch an order. In that function, you want to ensure that an order returns the ID of a menu item somewhere. For example:
function orderById(orderId) {
// ...content...
returns {
// ...order information...
menuItem: {
id: menuItemID
}
}
}
- This next step is an important bit to making this work. We need to tell the router to pass the ID of a menu item down to the
Menu
subgraph when we call for an Order
. To do this we create a resolve for our menuItem
field in our ResolversMap (or where you outline how things resolve with what functions). You can do that like so:
// Order resolvers
const resolvers = {
Query: {
orderById: ...
}
Order: {
menuItem: ({menuItem}: Order) => {
return {id: menuItem.id}
}
}
}
In the Menu subgraph
- I would start by making
Menu
a sharable entity.
type MenuItem @key(fields: "id") @shareable {
id: ID!
name: String!
price Float!
}
- This is the last important bit to making this work. When we set up our
Order
resolver to pass that ID down it has to be received by the Menu
subgraph. To do this, we create a __resolveReference
. Here I am also assuming that you have setup some sort of API for retrieving a menu item from you database. Under the Menu
subgraph resolvers, go ahead and add this:
// Menu resolvers
const resolvers = {
Query: {
menuItemByID: ...
}
MenuItem: {
__resolveReference: ({id}: MenuItem,{dataSources}: ServerContext) => {
return dataSources.menuItemAPI.menuItemByID(id)
}
}
}
What happens now, is that whenever the Router sees a request for an Order
, you ask to return a menuItem
within that Order
, it will know to call the Menu
subgraph to resolve menuItem
. Hope this helps, let me know if you have any questions