# install subgraphs & gateway deps
cd subgraphs/products && npm i
cd subgraphs/customer && npm i
cd subgraphs/shipping && npm i
cd gateway && npm i
# start the subgraphs
npm run start:dev
# ๐ Subgraph customer running at http://localhost:5010/
# ๐ Subgraph products running at http://localhost:5020/
# ๐ Subgraph shipping running at http://localhost:5030/
# exportAPOLLO_KEY=service:SECRET
# start the gateway
npm run start:gw
# ๐ Gateway ready at http://localhost:4000/
# shipping subgraph
query {
shippingReference {
id
orderNumber
shippingEstimate # query planner calls customer & products
}
}
Sample schema definition, utilizing @requires.
We can use @provides on an field resolved by another subgraph, to override their value. In this example, we have the field Product.description. While "description" can be resolved in the Product subgraph, the Shipping subgraph has its own value for it, and wants to return it for queries calling this service.
Observe the query
query InStockCount{
inStockCount(shippingId: "1") {
quantity
product {
id
description
}
}
}
// response
{
"data": {
"inStockCount": {
"quantity": 100,
"product": {
"id": "1",
"description": "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum."
}
}
}
}
This yields the query plan below. It instructs the gateway that for this query, it doesn't need to invoke the Product subgraph because the field is resolved here.
QueryPlan {
Fetch(service: "shipping") {
{
inStockCount(shippingId: $shippingId) {
quantity
product {
id
description
}
}
}
},
}
Now the Shipping subgraph doesn't return the Product.name for which the gateway then needs to call the Product subgraph
query InStockCount {
inStockCount(shippingId: "1") {
quantity
product {
id
name
description
}
}
}
//response
{
"data": {
"inStockCount": {
"quantity": 100,
"product": {
"id": "1",
"name": "Pants",
"description": "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum."
}
}
}
}
Execution plan:
QueryPlan {
Sequence {
Fetch(service: "shipping") {
{
inStockCount(shippingId: $shippingId) {
product {
__typename
id
description
}
quantity
}
}
},
Flatten(path: "inStockCount.product") {
Fetch(service: "products") {
{
... on Product {
__typename
id
}
} =>
{
... on Product {
name
}
}
},
},
},
}
export APOLLO_OTEL_EXPORTER_TYPE=collector
export APOLLO_OTEL_EXPORTER_HOST=collector
export APOLLO_OTEL_EXPORTER_PORT=4318
npm install @opentelemetry/node
@opentelemetry/plugin-http
@opentelemetry/plugin-express