Develop your graph
Use your graph to orchestrate API calls with Apollo Federation
In the previous guide, you set up a graph in GraphOS Studio and cloned a demo graph. In this guide, you will learn how to run your graph locally and develop it.
Let's start developing!
Develop your graph
A supergraph is made up of subgraphs and a router.
In this local development step, you'll do the following:
Locally run the subgraphs.
Locally run your router.
Query your router to ensure it's working as expected.
Love developer tooling? 🛠️
Run subgraphs
To start local development, you must first get the subgraphs in the retail demo up and running. From the root directory, install dependencies:
npm install
Then run the subgraphs:
npm run dev:subgraphs
In your terminal, you should see notifications for each subgraph:
Setting up [products] subgraph at http://localhost:4001/products/graphql
Setting up [orders] subgraph at http://localhost:4001/orders/graphql
Setting up [users] subgraph at http://localhost:4001/users/graphql
...
Keep these subgraphs up and running so that the router can query them.
Run router
With your subgraphs running, you can use Rover to start the router locally.
To do so, use the rover dev
command with the --supergraph-config
and --router-config
options.
The retail demo comes with supergraph-config-dev.yaml
and router-config-dev.yaml
YAML configuration files that include subgraph names, URLs, and router configurations.
In a different terminal window from the one where the subgraphs are running, run this command:
rover dev \
--supergraph-config supergraph-config-dev.yaml \
--router-config router-config-dev.yaml
When you first start the rover dev
process, you'll see the following happening in the terminal:
Rover loads the supergraph configuration and begins watching it for changes.
terminalsupergraph config loaded successfully ==> Watching router-config-dev.yaml for changes
Rover obtains the provided subgraph schemas, starts sessions for each of them, and begins watching them changes.
terminalstarting a session with the 'discovery' subgraph ==> Watching ./subgraphs/discovery/schema.graphql for changes starting a session with the 'checkout' subgraph ==> Watching ./subgraphs/checkout/schema.graphql for changes starting a session with the 'users' subgraph ==> Watching ./subgraphs/users/schema.graphql for changes starting a session with the 'inventory' subgraph ==> Watching ./subgraphs/inventory/schema.graphql for changes starting a session with the 'orders' subgraph ==> Watching ./subgraphs/orders/schema.graphql for changes starting a session with the 'shipping' subgraph ==> Watching ./subgraphs/shipping/schema.graphql for changes starting a session with the 'products' subgraph ==> Watching ./subgraphs/products/schema.graphql for changes starting a session with the 'reviews' subgraph ==> Watching ./subgraphs/reviews/schema.graphql for changes
Rover uses Apollo Federation to compose a supergraph schema by adding subgraph schemas one at a time. Rover recomposes the supergraph schema whenever it detects subgraph changes.
terminalcomposing supergraph with Federation v2.8.0 successfully composed after adding the 'products' subgraph
When composition completes successfully, Rover starts a locally running router session and provides it with the supergraph schema. Recomposition automatically reloads the router.
terminal==> your supergraph is running! head to http://localhost:4000 to query your supergraph
noteIf you see intermediate composition errors, ensure you've installed the latest version or Rover.
Nice! You've now got a supergraph running locally.
Query your router
To ensure everything works as expected, you can query your router in the Apollo Sandbox that Rover automatically starts up.
Open localhost:4000 in a browser to access your locally running router. It should look something like this:
Run the following query by copying and pasting it into the Operation window and then clicking the play button labeled ExampleQuery.
GraphQLquery ExampleQuery { listAllProducts { id title description mediaUrl variants { id price } } }
Confirm that once you run the operation, you see the following in the Response panel on the right:
Click to see responseJSON{ "data": { "listAllProducts": [ { "id": "product:1", "title": "Air Jordan 1 Mid", "description": "Air Jordan 1 Mid is a blue, grey and white sneaker from the iconic jordan brand", "mediaUrl": "https://sneakernews.com/wp-content/uploads/2022/06/air-jordan-1-mid-university-blue-grey-dx9276-100-6.jpg", "variants": [ { "id": "variant:1", "price": 600.25 }, { "id": "variant:2", "price": 20.12 } ] }, { "id": "product:2", "title": "Supreme x Tiffany & Co. Box Logo Tee", "description": "A classic Supreme vbox t-shirt in the signature Tiffany blue.", "mediaUrl": "https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcQWDHD3SSS98UAVKODaql7nrDTopfL4tcTnEltW8Yqy4hyDu4i5b70Wb3Y8-wACJIo5g-ZdRULPQKUmt7JfwiaSdgiOBz4pvU_YelKHUI4nhoXmMJPeh_tyWQ", "variants": [ { "id": "variant:4", "price": 600.25 }, { "id": "variant:5", "price": 600.25 }, { "id": "variant:6", "price": 600.25 }, { "id": "variant:7", "price": 600.25 }, { "id": "variant:8", "price": 600.25 } ] }, { "id": "product:3", "title": "THE MACKINAC 40MM", "description": "Established by Detroit's historic Bayview Yacht club, the days-long Port Huron to Mackinac Island regatta is one of the longest and most grueling freshwater races in the world.\n\nNamed for this legendary competition, the Shinola Mackinac is our first watch with automatic, single-eye chronograph yacht-timer functionality.\n\nIt's a precision instrument designed to be passed on for generations—just like the tradition that inspires it.", "mediaUrl": "https://shinola-m2.imgix.net/images/Products/20253783-sdt-012455107/S0120253783_F2_MAIN_01.png?h=1500&w=1500&bg=f7f7f7&auto=format,compress&fit=fillmax", "variants": [ { "id": "variant:9", "price": 3499.99 } ] }, ] } }
This operation requests a list of all products from the products subgraph. You can remove fields like
mediaUrl
or add fields likereleaseDate
to the operation to see how the reponse changes.Next, you'll execute an operation that demonstrates the power of federation.
Replace the example query in the Operation window with the following. Run it by clicking the play button, now labeled GetCart.
GraphQL# Get the current user's cart with all the items # and their product info as well as the price. query GetCart { user { id username shippingAddress cart { subtotal items { price inventory { inStock } product { title description mediaUrl } } } } }
In the Response panel, you should see an error like this:
Could not locate user by id. Please specify a valid x-user-id header like user:1
.This error appears because the operation retrieves a particular user's shopping cart given the user's ID. The operation expects the user ID to be in the request header. You can include it in the request headers in Sandbox by doing the following:
Open the Headers tab below the Operation editor.
Click + New header.
Enter
x-user-id
as the header key anduser:1
as the value.
Rerun the request. In the Response panel, confirm you see the following:
Click to see response$600.25—that must be some t-shirt.JSON{ "data": { "user": { "id": "user:1", "username": "User One", "shippingAddress": "123 Main St", "cart": { "subtotal": 620.37, "items": [ { "price": 20.12, "inventory": { "inStock": true }, "product": { "title": "Air Jordan 1 Mid", "description": "Air Jordan 1 Mid is a blue, grey and white sneaker from the iconic jordan brand", "mediaUrl": "https://sneakernews.com/wp-content/uploads/2022/06/air-jordan-1-mid-university-blue-grey-dx9276-100-6.jpg" } }, { "price": 600.25, "inventory": { "inStock": true }, "product": { "title": "Supreme x Tiffany & Co. Box Logo Tee", "description": "A classic Supreme vbox t-shirt in the signature Tiffany blue.", "mediaUrl": "https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcQWDHD3SSS98UAVKODaql7nrDTopfL4tcTnEltW8Yqy4hyDu4i5b70Wb3Y8-wACJIo5g-ZdRULPQKUmt7JfwiaSdgiOBz4pvU_YelKHUI4nhoXmMJPeh_tyWQ" } } ] } } } }
Excellent. You've used one request to your router to get data from across different services. In the last part of this local development step, you'll learn more about how the router accomplished this.
Inspect query plans
The GetCart
operation is powerful because it gathers data across various subgraphs: users
, products
, inventory
, and more.
Sandbox displays an operation's Query Plan to help you understand how the router intelligently orchestrates subrequests to these subgraphs.
A query plan is a blueprint for dividing a single incoming operation into one or more operations that are each resolvable by a single subgraph. You can view the query plan instead of the response by clicking Response and selecting Query Plan.
Query plans are a powerful tool for understanding operations, whether they're run locally or from client applications.
In the next step of this tutorial, you'll publish your locally running subgraph schemas to GraphOS Studio to learn more about your supergraph.
Next steps
To share and collaborate on your graph with your team, you need to publish it to GraphOS. Learn how, and see what else GraphOS has to offer in next guide.