Let’s say I have the following federated graph:
type Query {
products: [Product]!
}
// resolved by `discounts-service`
type Discount {
priceWithDiscount: Float
expired: Boolean
}
// resolved by `pricing-service`
type Price @key(fields: "sku") @extends {
sku: String!
amount: Int!
discount: Discount! @requires(fields: "amount")
}
// resolved by `products-service`
type Product @key(fields: "sku") {
sku: String!
title: String!
price: Price!
}
So, in summary, I have a query returning n products. Each Product
has a Price
, which has a Discount
node.
However, now let’s say that the Discount
is now tied to individual users. So now the resolver must know at least two properties about the user who is querying: its id
and segmentation
.
So we have an User
node like:
// resolved by `users-service`
type User @key(fields: "id") {
id: String!
name: String!
segmentation: String!
// ....
}
Now, how can I make the discounts-service
receive those properties (User data) in an efficient* manner in a Federated Apollo Schema?
*I’m saying efficient because a naive solution, such as just adding User
as @external
in the Product
/Price
node would make Apollo Router to call the users-service
for the same user for each product in the array, unnecessarily.
—
A possible solution would be adding parameters to the discount
node:
type Price @key(fields: "sku") @extends {
// ...
discount(userId: String!, segmentation: String!): Discount! @requires(fields: "amount")
}
However, such sollution requires the caller to first fetch the user data and the input values are untrustworthy since they’re given by the client and not fetched by the Apollo Router (i.e., an user can lie about its segmentation).
voyager11 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.