Router Quickstart

Run the router with GraphOS and Apollo-hosted subgraphs


Hello! This tutorial walks you through installing the router (GraphOS Router or Apollo Router Core) and running it in with GraphOS and some example Apollo-hosted subgraphs.

This quickstart helps you run a self-hosted instance of the router. If you create a cloud supergraph with Apollo GraphOS, Apollo provisions and hosts your supergraph's GraphOS Router for you.

Cloud supergraphs are recommended for organizations that don't need to host their router in their own infrastructure.

1. Download and extract the router binary

 note
The Apollo Router Core source code and all its distributions are made available under the Elastic License v2.0 (ELv2) license .

Download options

Automatic download (Linux, OSX, WSL)

If you have a bash-compatible terminal, you can download the latest version of the Apollo Router Core directly to your current directory with the following command:

Bash
1curl -sSL https://router.apollo.dev/download/nix/latest | sh

Manual download

Go to the Apollo Router Core's GitHub Releases page and download the latest .tar.gz file that matches your system. Currently, tarballs are available for the following:

  • Linux (x86_64)

  • Linux (aarch64)

  • macOS (Apple Silicon)

  • Windows (x86_64)

If a tarball for your system or architecture isn't available, you can build and run the router from source . You can also open an issue on GitHub to request the addition of new architectures.

After downloading, extract the file by running the following from a new project directory, substituting the path to the tarball:

Bash
1tar -xf path/to/file.tar.gz --strip-components=1

If you omit the --strip-components=1 option, the router executable is installed in a dist subdirectory.

Running the binary

You can now run the router from your project's root directory with the following command:

Bash
1./router

If you do, you'll get output similar to the following:

Text
1Apollo Router <version> // (c) Apollo Graph, Inc. // Licensed as ELv2 (https://go.apollo.dev/elv2)
2
3⚠️  The Apollo Router requires a composed supergraph schema at startup. ⚠️
4
5👉 DO ONE:
6
7  * Pass a local schema file with the '--supergraph' option:
8
9      $ ./router --supergraph <file_path>
10
11  * Fetch a registered schema from GraphOS by setting
12    these environment variables:
13
14      $ APOLLO_KEY="..." APOLLO_GRAPH_REF="..." ./router
15
16      For details, see the Apollo docs:
17      https://www.apollographql.com/docs/federation/managed-federation/setup
18
19🔬 TESTING THINGS OUT?
20
21  1. Download an example supergraph schema with Apollo-hosted subgraphs:
22
23    $ curl -L https://supergraph.demo.starstuff.dev/ > starstuff.graphql
24
25  2. Run the router in development mode with the supergraph schema:
26
27    $ ./router --dev --supergraph starstuff.graphql

This is because router requires a supergraph schema and we aren't providing it one! Let's fix that.

2. Download the example supergraph schema

For this quickstart, we're using example Apollo-hosted subgraphs, along with an example supergraph schema that's composed from those subgraph schemas.

From your project's root directory, run the following:

Bash
1curl -sSL https://supergraph.demo.starstuff.dev/ > supergraph-schema.graphql

This saves a supergraph-schema.graphql file with the following contents:

Click to expand
GraphQL
supergraph-schema.graphql
1schema
2  @link(url: "https://specs.apollo.dev/link/v1.0")
3  @link(url: "https://specs.apollo.dev/join/v0.3", for: EXECUTION) {
4  query: Query
5  mutation: Mutation
6}
7
8directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE
9
10directive @join__field(
11  graph: join__Graph
12  requires: join__FieldSet
13  provides: join__FieldSet
14  type: String
15  external: Boolean
16  override: String
17  usedOverridden: Boolean
18) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION
19
20directive @join__graph(name: String!, url: String!) on ENUM_VALUE
21
22directive @join__implements(
23  graph: join__Graph!
24  interface: String!
25) repeatable on OBJECT | INTERFACE
26
27directive @join__type(
28  graph: join__Graph!
29  key: join__FieldSet
30  extension: Boolean! = false
31  resolvable: Boolean! = true
32  isInterfaceObject: Boolean! = false
33) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR
34
35directive @join__unionMember(
36  graph: join__Graph!
37  member: String!
38) repeatable on UNION
39
40directive @link(
41  url: String
42  as: String
43  for: link__Purpose
44  import: [link__Import]
45) repeatable on SCHEMA
46
47scalar join__FieldSet
48
49enum join__Graph {
50  ACCOUNTS
51    @join__graph(name: "accounts", url: "https://accounts.demo.starstuff.dev/")
52  INVENTORY
53    @join__graph(
54      name: "inventory"
55      url: "https://inventory.demo.starstuff.dev/"
56    )
57  PRODUCTS
58    @join__graph(name: "products", url: "https://products.demo.starstuff.dev/")
59  REVIEWS
60    @join__graph(name: "reviews", url: "https://reviews.demo.starstuff.dev/")
61}
62
63scalar link__Import
64
65enum link__Purpose {
66  """
67  `SECURITY` features provide metadata necessary to securely resolve fields.
68  """
69  SECURITY
70
71  """
72  `EXECUTION` features provide metadata necessary for operation execution.
73  """
74  EXECUTION
75}
76
77type Mutation @join__type(graph: PRODUCTS) @join__type(graph: REVIEWS) {
78  createProduct(upc: ID!, name: String): Product @join__field(graph: PRODUCTS)
79  createReview(upc: ID!, id: ID!, body: String): Review
80    @join__field(graph: REVIEWS)
81}
82
83type Product
84  @join__type(graph: ACCOUNTS, key: "upc", extension: true)
85  @join__type(graph: INVENTORY, key: "upc")
86  @join__type(graph: PRODUCTS, key: "upc")
87  @join__type(graph: REVIEWS, key: "upc") {
88  upc: String!
89  weight: Int
90    @join__field(graph: INVENTORY, external: true)
91    @join__field(graph: PRODUCTS)
92  price: Int
93    @join__field(graph: INVENTORY, external: true)
94    @join__field(graph: PRODUCTS)
95  inStock: Boolean @join__field(graph: INVENTORY)
96  shippingEstimate: Int @join__field(graph: INVENTORY, requires: "price weight")
97  name: String @join__field(graph: PRODUCTS)
98  reviews: [Review] @join__field(graph: REVIEWS)
99  reviewsForAuthor(authorID: ID!): [Review] @join__field(graph: REVIEWS)
100}
101
102type Query
103  @join__type(graph: ACCOUNTS)
104  @join__type(graph: INVENTORY)
105  @join__type(graph: PRODUCTS)
106  @join__type(graph: REVIEWS) {
107  me: User @join__field(graph: ACCOUNTS)
108  recommendedProducts: [Product] @join__field(graph: ACCOUNTS)
109  topProducts(first: Int = 5): [Product] @join__field(graph: PRODUCTS)
110}
111
112type Review @join__type(graph: REVIEWS, key: "id") {
113  id: ID!
114  body: String
115  author: User @join__field(graph: REVIEWS, provides: "username")
116  product: Product
117}
118
119type User
120  @join__type(graph: ACCOUNTS, key: "id")
121  @join__type(graph: REVIEWS, key: "id") {
122  id: ID!
123  name: String @join__field(graph: ACCOUNTS)
124  username: String
125    @join__field(graph: ACCOUNTS)
126    @join__field(graph: REVIEWS, external: true)
127  reviews: [Review] @join__field(graph: REVIEWS)
128}

This file is all that the router needs to communicate with our subgraphs!

3. Run the router in development mode with the default configuration

Now from your project root, run the following:

sh
1./router --dev --supergraph supergraph-schema.graphql

The console output should look like the following:

sh
12022-06-29T22:23:24.266542Z  INFO apollo_router::executable: Apollo Router v0.9.5 // (c) Apollo Graph, Inc. // Licensed as ELv2 (https://go.apollo.dev/elv2)
22022-06-29T22:23:24.488286Z  INFO apollo_router::router: starting Apollo Router
32022-06-29T22:23:25.774334Z  INFO apollo_router::axum_http_server_factory: GraphQL endpoint exposed at http://127.0.0.1:4000/ 🚀

That's it! Running the router with the --dev flag enables a development mode that exposes Apollo Sandbox so you can run queries against the router.

⚠️ caution
Do not use the --dev flag in a non-development environment. It relaxes certain default configuration options to provide an improved local development experience (e.g., it exposes subgraph error messages to clients).Learn more about dev mode defaults.

Visit http://127.0.0.1:4000 to open Apollo Sandbox, inspect your entire supergraph, and run your first queries!

Next steps

Now that you know how to run the router with a supergraph schema, you can: