Apollo Docs
/

Tracking your GraphQL schema

A central hub for your GraphQL API


Apollo includes a schema registry that serves as a central hub for tracking your GraphQL schema. Adopting a shared schema registry for your project has many benefits:

  • Unlike introspection, which provides a snapshot of a particular server's current schema, the registry serves as a global source of truth for the schema. In small projects this frees you from always needing a running server to access the schema. At scale, it avoids issues related to running multiple servers that may not always be in sync (eg, rolling updates).
  • Much like a source control system, Apollo's schema registry tracks a full history of a schema and how it changed over time. This is valuable for understanding and collaborating on a GraphQL API, especially as your team grows.
  • Having a registry allows you to disable introspection in production – a recommended best practice for good security.
  • Tools like the Apollo VS Code extension can automatically fetch your schema from the registry and provide intellisense like field descriptions and deprecations directly in your editor.
  • Apollo's registry lets you track related variants of a schema, like staging or alpha versions. It's helpful to have these schema definitions handy without having to juggle running servers that implement them.

Using the Schema Registry

To get started using the schema registry, you'll need to make sure your repository is configured to be an Apollo project by:

  1. Installing the Apollo CLI
  2. Creating a .env file in the root of your project with an ENGINE_API_KEY
  3. Creating an apollo.config.js file at the root of your project and adding the right configuration

CLI commands

Once you have that set up, you'll be ready to start connecting to the schema regsitry using the CLI:

  • apollo service:push— push a new schema to the registry.
  • apollo service:check— calculate a local schema diff and compare the changes against live traffic to validate if the changes are safe or if they will break live running queries.

Install the Apollo CLI

To install the apollo CLI, ensure that node and npm are both installed, then run:

npm install --global apollo

Note: This guide will utilize the global installation method, but the apollo command can also be installed in a project's devDependencies and used via npm-scripts or npx.

Get your Engine API key

To get an API key, you will need to log in to Engine and create a new service by clicking the "Add Service" button. If you already have a service, get your API key by visiting your service's settings page. Once you have your API key, add it to your .env file like so:

ENGINE_API_KEY=service:foobar:d1rzyrmanmrZXxTTQLxghX

The Apollo CLI will be looking for your .env file because it uses your Engine API key to authenticate with the schema registry when it pushes your schema.

Note: Make sure your .env file is in the root of your project so the Apollo CLI knows where to find it. You can also export ENGINE_API_KEY as an environment variable.

Create an apollo.config.js file

The commands executed through the Apollo CLI will be looking for your Apollo config to inform their behavior. To set up schema registration, you'll need to configure a source that the CLI can fetch your schema from like so:

module.exports = {
  service: {
    endpoint: {
      url: "http://localhost:4000"
    }
    // OR
    localSchemaFile: './path/to/schema.graphql'
  }
};

The Apollo config documentation has more details and advanced configuration options for the apollo.config.js format.

Registering a schema

New versions of your schema are registered to Apollo by running the apollo service:push command from within your repository.

The CLI will know where to fetch your local schema from based on your apollo.config.js configuration. Every time you push a new version of your schema it will be logged to your graph's schema history.

Here's what running apollo service:push will look like:

~$ apollo service:push
  ✔ Loading Apollo Project
  ✔ Uploading service to Engine

id      schema        tag
──────  ────────────  ───────
190330  example-4218  current

Hooking into CI

To get the full value out of Apollo, your graph's schema history should be as accurately represented in the registry as possible. We highly recommend hooking apollo service:push into your repository's continuous delivery pipeline so your schema is updated in the registry on every deploy. This will ensure that you always get intellisense for your live-running schema in your VS Code extension, for example.

Here is a sample continuous delivery configuration for pushing a schema to Apollo using CircleCI:

version: 2

jobs:
  build:
    docker:
      - image: circleci/node:8

    steps:
      - checkout

      - run: npm install
      # CircleCI needs global installs to be sudo
      - run: sudo npm install --global apollo

      # Start the GraphQL server.  If a different command is used to
      # start the server, use it in place of `npm start` here.
      - run:
          name: Starting server
          command: npm start
          background: true

      # make sure the server has enough time to start up before running
      # commands against it
      - run: sleep 5

      # When running on the 'master' branch, push the latest version
      # of the schema to Apollo Engine.
      - run: |
          if [ "${CIRCLE_BRANCH}" == "master" ]; then
            apollo service:push --tag=master
          fi

Viewing schema change history

Changes made to your graph's schema over time can be viewed in Engine by browsing to the History page for your graph. Each time you push a new version of your schema, it will appear in your graph's history along with a list of the changes introduced in that version.

Schema history page in the Engine UI

Managing environments

Product cycles move fast and it's common for schemas to be slightly different across environments as changes make their way through your system. To support this, schemas pushed to the registry can be associated with specific variants of your graph (also referred to tags).

Apollo supports tracking multiple variants for every graph. A variant is just like a regular data graph. It has its own history of schemas, its own metadata store of metrics, and its own operation registry. Variants can be used to track ideas like staging environments, canaries, and deploys of experimental features destined for the production graph.

To get fully set up associating data sent to Apollo with variant information, you'll need to configure your CLI commands to send data with a --tag flag and configure your Apollo Server with a schemaTag option.

Registering schemas to a variant

To register your schema to a specific variant, simply add the --tag=<VARIANT> flag to your push command:

apollo service:push --tag=beta

Note: All schema pushes without a specified tag are registered under the default graph variant, current.

Associating metrics with a variant

There are a few ways to associate metrics reported to Engine with a specific variant:

  1. The best way to associate metrics with a variant of your graph is to start your server with an environment variable named ENGINE_SCHEMA_TAG that contains the name of your variant. This will link metrics sent to Engine with the value of that environment variable.
  2. Alternatively, add the schemaTag option to your Apollo Server configuration (works for Apollo Server 2.2+):
const server = new ApolloServer({
  ...
  engine: {
    apiKey: "<ENGINE_API_KEY>",
    schemaTag: "beta"
  }
});

Note: It's important that metrics are associated with the same tag as service:push if you want to track isolated data across different variants like production and staging.

Tools that use the schema registry

Keeping your schema up-to-date in Apollo's registry will ensure that you get the best experience from Apollo's tools that connect to the registry:

  • The Apollo VS Code extension provides built-in linting on queries by validating against the schema in your registry. It also annotates fields with their descriptions and with performance indicators collected in Apollo's trace warehouse.
  • The schema validation workflow protects your team from accidentally making breaking schema changes. It creates a diff between your local schema and the last schema pushed to the registry, and validates this diff against live traffic seen on your endpoint to warn you about problematic changes.
  • Your schema's full history and current usage can be seen in Apollo Engine. The History page tracks changes made over time, and the Explorer page shows which clients and which queries are using each field in your schema.