securing-a-subgraph Documentation

Official TypeScript developer resources and documentation for apollographql/securing-a-subgraph. Verified technical context for AI.

0 stars TypeScript TypeScript 1 file · ~59,340 tokens
RAW Doc

1. Project Overview & Quickstart (apollographql/securing-a-subgraph)

securing-a-subgraph

Open-source repository apollographql/securing-a-subgraph

Repository Details

Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.

2. Official Technical Reference & Guides (apollographql/docs)

File: README.md

This repository contains an archived version of the documentation platform for the Apollo Documentation site. It is no longer actively maintained, and the content here may be outdated. The project has undergone significant updates, and the latest documentation platform is now maintained in a private repository.

To update documentation content for Apollo’s open-source and source-available SDKs and libraries, you can submit pull requests to the relevant repository:

To submit feedback about the documentation, please use the Give Feedback option at the bottom of documentation content pages.


File: package.json

{
"name": "docs",
"private": true,
"scripts": {
"start": "./dev.sh",
"start:local": "DOCS_MODE=local npm start",
"start:client": "npm start -- ../apollo-client",
"start:platform-users": "npm start -- ../platform-users-docs",
"start:server": "npm start -- ../apollo-server",
"start:ios": "npm start -- ../apollo-ios-dev",
"start:kotlin": "npm start -- ../apollo-kotlin",
"start:federation": "npm start -- ../federation",
"start:rover": "npm start -- ../rover",
"start:router": "npm start -- ../router",
"build": "gatsby build",
"serve": "gatsby serve",
"test": "jest",
"postinstall": "npx playwright install",
"clean": "gatsby clean"
},
"dependencies": {
"@algolia/autocomplete-core": "^1.5.2",
"@algolia/autocomplete-plugin-algolia-insights": "^1.5.2",
"@algolia/autocomplete-preset-algolia": "^1.5.2",
"@apollo/brand": "^0.5.1",
"@apollo/chakra-helpers": "^2.0.0",
"@apollo/client": "^3.5.10",
"@apollo/icons": "^0.3.3",
"@apollo/pedia": "^4.1.4",
"@apollo/signup-tracer": "^2.0.0",
"@apollo/utm-grabber": "^1.3.1",
"@chakra-ui/gatsby-plugin": "^2.0.3",
"@chakra-ui/react": "^1.8.3",
"@colliercz/gatsby-transformer-gitinfo": "^1.3.0",
"@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0",
"@fec/remark-a11y-emoji": "^3.1.0",
"@fontsource/fira-code": "^5.0.17",
"@fontsource/inter": "^5.0.17",
"@jlengstorf/get-share-image": "^0.8.0",
"@loadable/component": "^5.15.2",
"@mdx-js/mdx": "^1.6.22",
"@mdx-js/react": "^1.6.22",
"@microsoft/api-extractor-model": "^7.28.2",
"@playwright/test": "^1.40.1",
"@svgr/webpack": "^5.5.0",
"@theowenyoung/gatsby-source-git": "^2.3.1",
"@typeform/embed-react": "^3.17.0",
"airtable": "^0.11.2",
"algoliasearch": "^4.12.1",
"apollo-algolia-transform": "^1.0.38",
"framer-motion": "^4.1.17",
"gatsby": "4.25.7",
"gatsby-plugin-algolia": "^0.24.0",
"gatsby-plugin-apollo": "^4.0.2",
"gatsby-plugin-apollo-onetrust": "git+https://github.com/apollographql/gatsby-plugin-apollo-onetrust.git#main",
"gatsby-plugin-env-variables": "^2.2.0",
"gatsby-plugin-google-gtag": "^4.3.0",
"gatsby-plugin-google-tagmanager": "^4.3.0",
"gatsby-plugin-loadable-components-ssr": "^4.2.0",
"gatsby-plugin-manifest": "^4.3.0",
"gatsby-plugin-mdx": "^2.14.0",
"gatsby-plugin-next-seo": "^1.9.0",
"gatsby-plugin-offline": "^5.3.0",
"gatsby-plugin-remove-serviceworker": "^1.0.0",
"gatsby-plugin-sitemap": "^5.3.0",
"gatsby-plugin-svgr": "^3.0.0-beta.0",
"gatsby-remark-autolink-headers": "^5.4.0",
"gatsby-remark-copy-linked-files": "^5.4.0",
"gatsby-remark-mermaid": "^3.0.0",
"gatsby-source-filesystem": "^4.4.0",
"gatsby-source-remote-file": "^0.5.2",
"gatsby-transformer-json": "^4.4.0",
"gatsby-transformer-remark": "^5.4.0",
"github-slugger": "^1.4.0",
"graphql": "^15.8.0",
"graphql-ws": "^5.8.2",
"https-browserify": "^1.0.0",
"interweave": "^12.9.0",
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
"lucide-react": "^0.127.0",
"mdast-util-from-markdown": "^0.8.5",
"node-fetch": "^2.6.7",
"path-browserify": "^1.0.1",
"pluralize": "^8.0.0",
"polished": "^4.1.4",
"prismjs": "^1.27.0",
"prop-types": "^15.7.2",
"puppeteer": "^10.4.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-helmet-async": "^1.2.1",
"react-instantsearch": "^7.3.0",
"react-instantsearch-dom": "^6.40.4",
"react-markdown": "^8.0.0",
"react-medium-image-zoom": "^5.1.10",
"react-player": "^2.10.1",
"react-use": "^17.3.2",
"rehype": "^12.0.0",
"rehype-autolink-headings": "^5.1.0",
"rehype-react": "^7.0.3",
"remark": "^14.0.2",
"remark-mermaidjs": "^5.0.2",
"remark-react": "^9.0.1",
"remark-typescript": "^0.6.1",
"search-insights": "^1.8.0",
"stream-http": "^3.2.0",
"unist-util-visit": "^2.0.3",
"uuid": "^8.3.2",
"vfile": "^5.3.7"
},
"devDependencies": {
"@google-analytics/data": "^4.4.0",
"@trevorblades/eslint-config": "^7.2.7",
"cpx": "^1.5.0",
"eslint": "^7.32.0",
"eslint-plugin-mdx": "^1.11.1",
"jest": "^27.4.5",
"netlify-cli": "^15.0.2",
"netlify-plugin-cache": "^1.0.3"
},
"volta": {
"node": "16.15.1"
}
}


File: plugins/gatsby-plugin-apollo-client-api-doc/package.json

{
"name": "gatsby-plugin-apollo-client-api-doc"
}


{
"name": "gatsby-plugin-check-links"
}


File: plugins/gatsby-plugin-combine-redirects/package.json

{
"name": "gatsby-plugin-combine-redirects"
}


File: plugins/gatsby-plugin-local-docs/package.json

{
"name": "gatsby-plugin-local-docs"
}


File: plugins/remark-mermaid-cached/package.json

{
"name": "remark-mermaid-cached"
}


File: sources/local.yml

mapping of local source paths to the location of their content

TODO: maybe try sourcing content from outside the src directory?

https://github.com/gatsbyjs/gatsby/issues/5510

/: src/content/basics
graphos: src/content/graphos/basics
graphos/metrics: src/content/graphos/metrics
graphos/cloud-routing: src/content/graphos/cloud-routing
graphos/delivery: src/content/graphos/delivery
graphos/org: src/content/graphos/org
graphos/explorer: src/content/graphos/explorer
graphos/enterprise: src/content/graphos/enterprise
technotes: src/content/technotes
community: src/content/community
odyssey: src/content/odyssey


File: src/content/basics/changelog.mdx


title: Apollo product changelogs

Each Apollo product maintains its own changelog, usually in its GitHub repository. You can find links to product changelogs below.

Changelogs


File: src/content/basics/config.json

{
"title": "Home",
"sidebar": {
"Home": "/",
"What is GraphOS?": "/intro/platform",
"About GraphQL": {
"Why Adopt GraphQL?": "/intro/benefits",
"Glossary": "/resources/glossary",
"FAQ": "/resources/faq",
"Principled GraphQL": "https://principledgraphql.com"
},
"Release Policies": {
"Product Launch Stages": "/resources/product-launch-stages",
"Elastic License v2 FAQ": "/resources/elastic-license-v2-faq"
},
"Changelogs": "changelog",
"GraphQL Summit 2024":"https://summit.graphql.com/?utm_campaign=docs_sidebar"
}
}


File: src/content/basics/index.mdx


title: Documentation toc: true subtitle: ' '

import {
ApolloClientIcon,
ApolloIOSIcon,
ApolloKotlinIcon,
CSharpIcon,
CircleCheckIcon,
DiscordIcon,
DiscourseIcon,
GitHubIcon,
GraphOSIcon,
GraphQLIcon,
JavaIcon,
NodeJsIcon,
RocketIcon,
TwitterIcon,
TypescriptIcon,
YoutubeIcon
} from '../../components/Icons';
import {ButtonGroup, VStack} from '@chakra-ui/react';
import {
CommunityButton,
Docset,
DocsetGrid,
GradientCard
} from '../../components/HomePage';
import {SummitCallout} from '../../components/SummitCallout';

Apollo provides the developer platform and tools to unify your data and services into a supergraph—a single distributed GraphQL API.
Apollo makes GraphQL work for you at any stage and any scale, whether you're just getting started, building your first API, querying an API, or migrating your platform onto the supergraph.

For architects

<GradientCard
icon={}
title="Build a supergraph"
description="Use Apollo GraphOS to define, build, connect, and observe all of your data services together in a supergraph."
path="/graphos"
cta="Learn about GraphOS"
/>

<Docset
icon={}
title="Deploy reference architecture"
description="Set up an enterprise GraphOS deployment by following Apollo's reference architecture."
path="/graphos/enterprise/reference-architecture"
cta="Explore reference architecture"
/>
<Docset
icon={}
title="Adopt best practices"
description="Assess your graph with the Supergraph Architecture Framework (SAF) and get tailored recommendations to improve it."
path="/graphos/enterprise/supergraph-architecture-framework"
cta="Learn about SAF"
/>

For API developers

} title="Node.js" description="Build a production-ready API that handles multiple data sources with Apollo Server." path="/apollo-server" cta="Explore Apollo Server docs" /> } title="TypeScript" description="Explore a tutorial on implementing a GraphQL API with TypeScript and Apollo Server." path="https://www.apollographql.com/tutorials/intro-typescript" cta="Begin tutorial" /> } title="Java" description="Explore a tutorial on implementing a GraphQL API with Java and DGS." path="https://www.apollographql.com/tutorials/intro-dgs" cta="Begin tutorial" /> } title="C#" description="Explore a tutorial on implementing a GraphQL API with .NET (C#) and Hot Chocolate." path="https://www.apollographql.com/tutorials/intro-hotchocolate" cta="Begin tutorial" />

For client developers

Apollo Client is the industry-standard GraphQL client library. Execute GraphQL operations, cache their results, and manage your application's state in one place.

<Docset icon={} title="React / JS" path="/react" />

<Docset icon={} title="iOS" path="/ios" />
<Docset icon={} title="Kotlin" path="/kotlin" />

For GraphQL newcomers

<GradientCard
icon={}
title="Improve developer velocity"
description="Understand how GraphQL and Apollo help enhance developer experience and ship features faster."
path="/intro/benefits"
cta="Learn about GraphQL"
/>

Join our community

We love hearing from you! Here are a few ways to connect with us and other Apollo community members.

<CommunityButton
aria-label="Community GitHub"
href="https://github.com/apollographql"
icon={}
/>
<CommunityButton
aria-label="Community YouTube"
href="https://youtube.com/apollographql"
icon={}
/>
<CommunityButton
aria-label="Community Forums"
href="https://community.apollographql.com"
icon={}
/>
<CommunityButton
aria-label="Community Discord"
href="https://discord.gg/yFZJH2QYrK"
icon={}
/>
<CommunityButton
aria-label="Community Twitter"
href="https://twitter.com/apollographql"
icon={}
/>


File: src/content/basics/devtools/cli.mdx


title: The Apollo CLI

All apollo service:* commands are now deprecated in favor of commands in the Rover CLI.

The Apollo CLI provides useful commands for interacting with every component of the Apollo platform, including Apollo Client, Apollo Server, and GraphOS Studio.

Download and install

The Apollo CLI is available as an npm package.

If your project uses npm, we recommend installing the Apollo CLI locally by adding it to your project's devDependencies, like so:

bash showlinenumbers=false
npm install -D apollo

This helps make sure that all your project's collaborators have the same version of the Apollo CLI installed.

Global installation

You can install the Apollo CLI globally in your development environment with the following command:

bash showlinenumbers=false
npm install -g apollo

Provide an API key

Like all other tools, the Apollo CLI requires an API key to communicate with GraphOS Studio. For each of your projects, obtain a graph API key for the project's associated graph, and set that key as the value of APOLLO_KEY in your application's .env file:

js title=".env"
APOLLO_KEY=service:docs-example-graph:NYKgCqwfCyYPIm84WVXCdw

Alternatively, you can provide an API key to individual CLI commands with the --key option:

text
apollo client:check --graph=MyGraph --key=service:docs-example-graph:NYKgCqwfCyYPIm84WVXCdw

Supported commands

Most of the Apollo CLI's commands are in the following namespaces:

  • client (such as apollo client:codegen) for interactions involving Apollo Client and GraphOS Studio
  • service (such as apollo service:check) for interactions involving Apollo Server and GraphOS Studio

All apollo service:* commands are now deprecated in favor of commands in the Rover CLI.

For a full list of commands in a particular namespace, use the apollo help command:

Omit npx from the example commands below if you installed the Apollo CLI globally.

text
$ npx apollo help client
Check a client project against a pushed service

USAGE
  $ apollo client:COMMAND

COMMANDS
  client:check            Check a client project against a pushed service
  client:codegen          Generate static types for GraphQL queries. Can use the
                          published schema in the Apollo registry or a
                          downloaded schema.
  client:download-schema  Download a schema from Apollo or a GraphQL endpoint in
                          JSON or SDL format
  client:extract          Extract queries from a client
  client:push             Register operations with Apollo, adding them to the
                          safelist

You can also obtain the full set of options for an individual command like so:

text
$ npx apollo help client:codegen

File: src/content/basics/devtools/editor-plugins.mdx


title: Apollo extension for VS Code

The Apollo VS Code extension provides an all-in-one tooling experience for developing apps with Apollo.

The extension enables you to:

Getting started

To get all the benefits of the VS Code experience, it's best to link the schema that is being developed against before installing the extension. The best way to do that is by publishing a schema to the Apollo schema registry. After that's done:

  1. Create an apollo.config.js file at the root of the project.
    Alternatively, you can create a cjs, mjs, or ts file with the same configuration.
  2. Obtain a Personal API key from GraphOS Studio.

Setting up an Apollo config

For the VS Code plugin to know how to find the schema, it needs to be linked to either a published schema or a local one. To link a project to a published schema, edit the apollo.config.js file to look like this:

js
module.exports = {
  client: {
    service: 'my-graphql-app'
  }
};

The service name is the name of the graph you've created in GraphOS Studio.

See additional configuration options.

Setting up the `.env` file

To authenticate with GraphOS Studio to pull down your schema, create a .env file in the same directory as the apollo.config.js file. This should be an untracked file (that is, don't commit it to Git).

Then go to your User Settings page in GraphOS Studio to create a new Personal API key.

It is best practice to create a new API key for each member of the team and name the key so its easy to find and revoke if needed. This will be easier to manage in the future.

After the key is found, add the following line to the .env file:

bash showlinenumbers=false
APOLLO_KEY=<enter copied key here>

After this is done, VS Code can be reloaded and the Apollo integration will connect to GraphOS Studio to provide autocomplete, validation, and more.

Local schemas

Sometimes it may make sense to link the editor to a locally running version of a schema to try out new designs that are in active development. To do this, the apollo.config.js file can be linked to a local service definition:

js
module.exports = {
  client: {
    service: {
      name: 'my-graphql-app',
      url: 'http://localhost:4000/graphql'
    }
  }
};

Linking to the local schema won't provide all features, such as switching graph variants and performance metrics.

Local schema files

You might not always have a running server to link to, so the extension also supports linking to a local schema file.
This is useful for working on a schema in isolation or for testing out new features.
To link to a local schema file, add the following to the apollo.config.js file:

js
module.exports = {
  client: {
    service: {
      // can be a string pointing to a single file or an array of strings
      localSchemaFile: './path/to/schema.graphql'
    }
  }
};

Client-only schemas

One of the best features of the VS Code extension is the automatic merging of remote schemas and local ones when using integrated state management with Apollo Client. This happens automatically whenever schema definitions are found within a client project. By default, the VS Code extension will look for all JavaScript, TypeScript and GraphQL files under ./src to find both the operations and schema definitions for building a complete schema for the application.

Client side schema definitions can be spread throughout the client app project and will be merged together to create one single schema. The default behavior can be controlled by adding specifications to the apollo.config.js:

js
module.exports = {
  client: {
    service: 'my-graphql-app',
    // array of glob patterns
    includes: ['./src/**/*.js'],
    // array of glob patterns
    excludes: ['**/__tests__/**']
  }
};

Get the extension

Once you have a config set up and a schema published, install the Apollo GraphQL extension, then try opening a file containing a GraphQL operation.

When a file open, clicking the status bar icon will open the output window and print stats about the project associated with that file. This is helpful when confirming the project is setup properly.

Features

Apollo for VS Code brings many helpful features for working on a GraphQL project.

Intelligent autocomplete

Once configured, editors have full knowledge of the schema clients are running operations against, including client-only schemas (for things like local state mutations). Because of this, editors have the ability to autocomplete fields and arguments as you type.

Inline errors and warnings

Editors can use local or published schemas to validate operations before running them. Syntax errors, invalid fields or arguments, and even deprecated fields instantly appear as errors or warnings right in your editor, ensuring all developers are working with the most up-to-date production schemas.

Inline field type information

Because of GraphQL's strongly typed schema, editors not only know about which fields and arguments are valid, but also what types are expected. Hover over any type in a valid GraphQL operation to see what type that field returns and whether or not it can be null.

Performance insights

GraphQL's flexibility can make it difficult to predict the cost of an operation. Without insight into how expensive an operation is, developers can accidentally write queries that place strain on their graph API's underlying backends. Thanks to the Apollo platform's integration with VS Code and our trace warehouse, teams can avoid these performance issues altogether by instantly seeing the cost of a query right in their editor.

The VS Code extension will show inline performance diagnostics when connected to a service with reported metrics in GraphOS Studio. As operations are typed, any fields that take longer than 1 ms to respond will be annotated to the right of the field inline! This gives team members a picture of how long the operation will take as more and more fields are added to operations or fragments.

Syntax highlighting

Apollo's editor extension provides syntax highlighting for all things GraphQL, including schema definitions in .graphql files, complex queries in TypeScript, and even client-only schema extensions. Syntax highlighting for GraphQL works out-of-the-box for .graphql, .gql, .js and .ts file types.

Navigating large codebases can be difficult, but the Apollo GraphQL extension makes this easier. Right-clicking on any field in operations or schemas gives you the ability to jump to (or peek at) definitions, as well as find any other references to that field in your project.

Graph variant switching

Apollo supports publishing multiple versions (variants) of a schema. This is useful for developing on a future development schema and preparing your clients to conform to that schema. To switch between graph variants, open the Command Palette (cmd + shift + p on mac), search "Apollo" and choose the "Apollo: Select Schema Tag" option.

Troubleshooting

The most common errors are configuration errors, like a missing .env file or incorrect service information in the apollo.config.js file. Please see the Apollo config docs for more configuration guidance.

Other errors may be caused from an old version of a published schema. To reload a schema, open the Command Palette (cmd + shift + p on mac), search "Apollo" and choose the "Apollo: Reload Schema" option.

Sometimes errors will show up as a notification at the bottom of your editor. Other, less critical, messages may be shown in the output pane of the editor. To open the output pane and get diagnostic information about the extension and the current service loaded (if working with a client project), just click the "Apollo GraphQL" icon in the status bar at the bottom.

If problems persist or the error messages are unhelpful, open an issue in the vscode-graphql repository.

Additional Apollo config options

You can add these configurations to your Apollo config file.

`client.tagName`

Optional - custom tagged template literal.

When using GraphQL with JavaScript or TypeScript projects, it is common to use the gql tagged template literal to write out operations. Apollo tools look through your files for the gql tag to extract your queries, so if you use a different template literal, you can configure it like so:

js
module.exports = {
  client: {
    tagName: "graphql", // highlight-line
    service: ...
  }
};

File: src/content/basics/intro/benefits.md


title: Why adopt GraphQL?

Managing data in modern applications is challenging. Most applications require:

  • Distinct frontend clients for multiple platforms (web, iOS, etc.), each with different data requirements
  • A backend that serves data to clients from multiple sources (Postgres, Redis, etc.)
  • Complex state and cache management for both the frontend and the backend

By adopting GraphQL and Apollo, you can reduce these challenges considerably. GraphQL's declarative model helps you create a consistent, predictable API you can use across all your clients. As you add, remove, and migrate backend data stores, that API doesn't change from the client's perspective.

Even with many other advantages, GraphQL's single greatest benefit is the developer experience it provides. It's straightforward to add new types and fields to your API, and similarly straightforward for your clients to begin using those fields. This helps you design, develop, and deploy features quickly.

Combined with Apollo open-source libraries, complex considerations like caching, data normalization, and optimistic UI rendering become straightforward as well.

GraphQL provides declarative, efficient data fetching

GraphQL's declarative approach to data fetching provides significant performance and quality-of-life improvements over a REST API.

Consider a webpage that displays a list of adorable pets that are available for adoption at local animal shelters. 🐶

Using REST

Using REST, the page might need to:

  1. GET a list of shelters and their corresponding pet_ids from the /api/shelters endpoint
  2. GET each individual pet's details (name, photo URL, etc.) with a separate request to /api/pets/PET_ID

This solution requires multiple dependent network requests, which can result in slower page loads and additional battery consumption on mobile devices. This logic is also difficult to reuse on other pages that display slightly different data.

Using GraphQL

Using GraphQL, the page can obtain all this data with a single query to a single endpoint. That query looks like this:

graphql
query GetPetsByShelter {
  shelters {
    name
    pets {
      name
      photoURL
    }
  }
}

This query describes the shape of the data we want to receive from the GraphQL server. The server takes care of combining and filtering backend data to return exactly what we ask for. This keeps payload sizes small, especially compared to a REST endpoint that might return hundreds of unnecessary fields.

To execute a query like the one above, the page uses a GraphQL client such as Apollo Client, with code that resembles the following (in the case of a React app):

jsx title="mainpage.jsx"
// Define the query
const GET_PETS_BY_SHELTER = gql`
  query GetPetsByShelter {
    shelters {
      name
      pets {
        name
        photoURL
      }
    }
  }
`;

function MainPage() {
  // Execute the query within the component that uses its result
  const { loading, error, data } = useQuery(GET_PETS_BY_SHELTER);

  if (error) return <Error />;
  if (loading || !data) return <Fetching />;

  // Populate the component using the query's result
  return <PetList shelters={data.shelters} />;
}

Apollo Client's useQuery hook takes care of the request lifecycle from start to finish, including tracking loading and error states for you. There's no middleware to set up or boilerplate to write before making your first request. All you need to do is describe the data your component needs and let Apollo Client do the heavy lifting. 💪

GraphQL enables powerful tooling

Thanks to GraphQL's strong typing and built-in support for introspection, developer tools for GraphQL are extremely powerful. These tools let you do things like:

  • Explore the full structure of a schema, complete with docstrings
  • Compose new operations with live validation and autocomplete
  • Register your schema with a management service that tracks and checks changes

What is Apollo GraphOS?

Apollo provides a cloud-hosted collection of tools that help you build your graph, measure its performance, and grow it safely. These tools are together known as Apollo GraphOS.

After registering your schema with GraphOS, you can use the GraphOS Studio Explorer to inspect all its types and fields.
You can also build and run queries against your running server.

Apollo Client DevTools

The Apollo Client DevTools extension for Chrome and Firefox enables you to inspect your Apollo Client cache, track active queries, and view mutations. It also includes an embedded version of the Explorer, which helps you test queries while you're working on frontend code.

GraphQL is production-ready

GraphQL's adoption has risen steadily since Facebook published the original specification in 2015. For more and more organizations, the benefits of GraphQL have taken it from a curious engineer's hack-week experiment to the heart of the enterprise data layer.

GraphQL scales with the requirements of even the largest organizations, largely because of its powerful tooling and its compatibility with a federated architecture.

In a federated architecture, also known as a supergraph, a single GraphQL schema is split across multiple backend services. Each team in an organization can then own exactly the services (and the corresponding parts of the schema) that they should.

Organizations using GraphQL

Here are a few blog posts from organizations that have benefited from adopting GraphQL in their production environment:

GraphQL trade-offs

When deciding whether to adopt a technology, it's just as important to understand the technology's limitations as it is to understand its benefits.

Consider the following trade-offs when using GraphQL:

Change management

GraphQL introduces a new conceptual model for representing and interacting with data. An organization that's comfortable with this model can design, implement, and ship features quickly. However, the process of becoming comfortable with this model takes time.

  • Frontend developers must come up to speed with a new API for fetching and manipulating data.
  • Backend developers must come up to speed with how to handle incoming requests from the frontend.
  • Developers across the organization must collaborate on a single, product-driven GraphQL schema and appoint individuals as the official maintainers of that schema.

The Apollo docs, blog, and community forum are all here to help your organization adopt GraphQL and take full advantage of it.

Potential for slow operations

Your GraphQL schema defines which types and fields your clients can query. Your GraphQL server's resolvers define how those types and fields are populated from your data stores.

Depending on your schema and your resolver definitions, your server might inadvertently support GraphQL operations that execute slowly, or even max out your server's resources.

Consequently, it's important to design your schema such that it supports the operations your clients need, without supporting unnecessary operations that affect performance. It's also helpful to set up trace reporting for your GraphQL server, enabling you to identify and improve slow operations.

Learn about query-driven schema design.

Incompatibility with web browser caching

Although Apollo Client provides powerful client-side caching features, those features often require some configuration to get the most out of them. The automatic caching provided by your web browser does not interact well with GraphQL.

Web browsers cache fetched data according to its URL. With GraphQL, you fetch all data from the same URL (the URL of your GraphQL server). Consequently, you can't rely on the cached value for this URL.


File: src/content/basics/intro/platform.mdx


title: The Apollo GraphOS platform

Apollo GraphOS is the platform for building, managing, and scaling a supergraph: a unified network of your organization's microservices and their data sources—all composed into a single distributed API.

With one query to your supergraph's router, an application client can fetch data from any combination of your services:

mermaid
flowchart LR;
  clients(Clients);
  subgraph "GraphOS";
  router(["Graph<br/>Router"]);
  end;
  subgraph "Your infrastructure";
  subgraphA[Users<br/>API];
  subgraphB[Products<br/>API];
  dbA[( )];
  dbB[( )];
  router -->|Sub-query| subgraphA & subgraphB;
  subgraphA --- dbA;
  subgraphB --- dbB;
  end;
  clients -.->|Query| router;
  class clients secondary;

Clients query your supergraph with a powerful language called GraphQL, which enables them to retrieve exactly the data they need, with no overfetching. Your supergraph's architecture is not exposed—clients send queries to a single endpoint (your router), no matter what data they need.

graphql title="example client query"
# This single query fetches data
# from both APIs shown above.
query GetCurrentUserWishlist {
  currentUser {
    id
    name
    wishlistedProducts {
      id
      name
      inStock
    }
  }
}
json title="example router response"
{
  "data": {
    "currentUser": {
      "id": "abc",
      "name": "Katherine Johnson",
      "wishlistedProducts": [
        {
          "id": "123",
          "name": "Coffee thermos",
          "inStock": true
        }
      ]
    }
  }
}

The supergraph is not a replacement for your existing infrastructure. Instead, it's a methodology for interconnecting your existing infrastructure, to make it more accessible and useful for everyone who interacts with your data.

What's in GraphOS?

The GraphOS platform provides an ever-growing collection of tools and services to help you build your supergraph and scale it safely alongside your organization.

These features are core to GraphOS:

  • Cloud routing
    • GraphOS automatically provisions and hosts a router for each of your supergraphs. Clients query your router instead of your individual services (also called subgraphs). This enables the router to automatically collect operation metrics that you can then visualize in GraphOS Studio.
  • The schema registry
    • GraphOS tracks the schemas for all your GraphQL APIs, and it also handles composing those schemas into one supergraph schema for your router.
  • Safe schema delivery
    • The schema checks feature of GraphOS enables you to verify whether proposed changes to one of your services will cause an issue with other services, or with any of your existing clients.
    • Whenever you update a service's schema, GraphOS composes a new supergraph schema for your router. If composition succeeds, your router automatically begins using its new schema.
    • You can view the results of each launch that takes place whenever you update a service's schema, helping you resolve any issues that might occur.
  • An interface for every use case
    • GraphOS Studio is the primary web interface for GraphOS. Among other capabilities, you use Studio to create your organization and its supergraphs, view schemas and metrics, and test out operations in the Explorer.
    • The Rover CLI is the primary command-line interface for GraphOS. Among other capabilities, you use Rover to publish schemas to the registry, run schema checks from CI, and test out your supergraph within your development environment.
    • If you want to automate your own workflows outside of Studio or Rover, you can use the official GraphOS Platform API to do so. We'll expose more GraphOS capabilities through the Platform API over time.

To learn more about these and many more GraphOS features, see the complete GraphOS documentation.

What's in a supergraph?

If GraphOS is the platform for building and managing supergraphs, it's important to understand what's in a supergraph.

Every supergraph uses an open architecture called Apollo Federation, which consists of the following parts:

mermaid
flowchart LR;
  clients(Clients);
  subgraph "GraphOS";
  router(["Graph<br/>Router"]);
  end;
  subgraph "Your infrastructure";
  subgraphA[GraphQL API<br/>A];
  subgraphB[GraphQL API<br/>B];
  dbA[( )];
  dbB[( )];
  router --- subgraphA & subgraphB;
  subgraphA --- dbA;
  subgraphB --- dbB;
  end;
  clients -.- router;
  class clients secondary;
  • The graph router
    • The graph router serves as the client-accessible entry point to your supergraph. It receives all incoming queries.
    • As its name suggests, the router "routes" each incoming query to the appropriate combination of subgraphs (see the next item). It's also responsible for combining multiple subgraph responses into a single response for the client.
    • GraphOS can take care of provisioning and hosting your supergraph's router for you.
  • One or more subgraphs
    • Your GraphQL APIs each contribute a subset of your supergraph's available data, so we call them subgraphs Clients don't query your subgraphs directly—only your router does.
    • Usually, each of your existing microservices acts as a different subgraph.
  • Backing data sources (databases, REST APIs, etc.)
    • Your subgraphs use these to populate data for incoming queries.

The diagram above shows a basic supergraph with a GraphOS Router, two subgraphs, and two corresponding data sources.

The following video provides a helpful visualization of how the Apollo Federation architecture helps organizations scale with their data:

Why adopt a supergraph?

Adopting a supergraph significantly improves the developer experience for every team (both internal and external) that interacts with your organization's data. These improvements enable developers to ship products and features more quickly, with greater confidence in their reliability and performance.

How do I implement a supergraph?

To implement a supergraph, you set up its individual parts: the graph router and your subgraphs. Apollo provides libraries and tools for setting up each part. And more importantly, we provide tutorials to help you.

Tutorials

  • If you're new to GraphQL, we recommend starting your supergraph journey with the Lift-off tutorial series.
    • Familiarizing yourself with fundamental GraphQL concepts is an important prerequisite to getting the most out of your supergraph.
  • If you're already using GraphQL, we recommend jumping in with your first GraphOS cloud supergraph. See the quickstart.
    • You can also check out the Voyage tutorial series to learn how to create a complete supergraph from scratch.

Implementing the router

If you create a cloud supergraph with GraphOS, Apollo provisions and hosts your supergraph's router for you.

For enterprise organizations that need to run their router in their own infrastructure, Apollo provides two libraries that can act as a router:

  • The GraphOS Router (strongly recommended)
    • The GraphOS Router is powered by the Apollo Router Core—a high-performance binary written in Rust that adds minimal latency to request processing, even with extremely high traffic.
    • Because the Apollo Router Core is released as a precompiled binary, you don't need to write any boilerplate code around it to deploy it to your backend. All it needs is a configuration file for any behavior you want to customize.
    • Cloud supergraph routers use the GraphOS Router under the hood.
  • Apollo Server with @apollo/gateway
    • This is Apollo's open-source Node.js GraphQL server library, which you can configure to act as a supergraph gateway.

If you get started with one of these libraries and later decide to switch to the other, you can do so without making any changes to the rest of your supergraph.

Implementing subgraphs

Each subgraph is itself a GraphQL API. Therefore, it uses a GraphQL server library to handle queries forwarded along by your graph router.

To act as a subgraph, a GraphQL server library needs to support the Apollo Federation subgraph specification. Fortunately, many popular libraries do. See Federation-compatible subgraph implementations.

Feel free to use whichever server library best suits your organization. Different subgraphs can even use completely different libraries, which is helpful if your various microservices use different languages.

How do clients query my supergraph?

To client applications, your supergraph appears the same as any other GraphQL API. Therefore, they query it with the same client libraries.

Apollo provides GraphQL client libraries for the following platforms:

These are all customizable, open-source libraries with powerful caching and state management features. Client-side caching enables an application to locally replicate the parts of your supergraph that it cares about. The application can then query itself for data if it's already present, which dramatically improves performance by eliminating redundant network requests.

Where do I start?

We have loads of helpful resources to help you start your supergraph journey:

Looking for additional guidance? Share a question in our community forums and we'll help point you in the right direction.


File: src/content/basics/resources/elastic-license-v2-faq.md


title: Apollo FAQ on Licensing under Elastic License v2 (ELv2)

Our source code for Apollo Federation (including Gateway and Federation libraries starting with the v2.x versions, and all versions of the Apollo Router Core), the Rover composition add-on, and Workbench will be licensed under the Elastic License v2 (ELv2). Previous versions of the Gateway and Federation libraries (0.x) remain MIT-licensed.

We chose ELv2 because of its permissiveness and simplicity. We're following the well-paved path of other great infrastructure projects like Elasticsearch and MongoDB that have implemented similar source code licenses to preserve their communities. Our community and customers still have no-charge and open access to use, modify, redistribute, and collaborate on the code. ELv2 also protects our continued investment in developing freely available libraries and developer tools by restricting cloud service providers from offering Apollo Federation as a service.

What is allowed with the Elastic License v2?

The Elastic License v2 applies to our distribution and the source code of the Apollo Federation including its libraries, Apollo Gateway, Apollo Router Core. Our goal with ELv2 is to be as permissive as possible, while protecting our product and brand from abuse. The license allows the free right to use, modify, create derivative works, and redistribute, with three simple limitations:

  1. You may not provide the products to others as a managed service.
  2. You may not circumvent the license key functionality or remove/obscure features protected by license keys.
  3. You may not remove or obscure any licensing, copyright, or other notices.

Please reach out to us at [email protected] if you're unsure whether your use case falls outside these limitations.

I'm using the MIT-licensed 0.x version of the Apollo Federation gateway and libraries in my project. How does ELv2 affect me?

We will continue to actively maintain the MIT-licensed 0.x Apollo Federation packages until the end of 2022, by merging compatibility updates, bug fixes, security patches, and select feature enhancements. All 0.x packages will be published to npm, just as before. We want you to have a smooth and gradual migration to Apollo Federation 2 at your own pace.

What license applies to me if I'm using the new Apollo Federation 2 packages?

ELv2 applies to the source code and any distribution (for example, on npmjs.com) of Apollo Federation v2 including its libraries, Apollo Gateway beginning with version 2.x releases, and all versions of the Apollo Router Core.

I'm a maintainer of a subgraph framework, library, or platform that supports Apollo Federation. How does ELv2 affect me?

It doesn't! The @apollo/subgraph library will remain MIT-licensed for all versions of Apollo Federation, so you can freely embed it in any subgraph library, framework, or platform with full OSS license compatibility. For more information on how to make your subgraph library work with Apollo Federation, check out our subgraph maintainers guide.

I use the Apollo Federation Gateway, Router or libraries internally at my company. How does ELv2 affect me?

Your internal use won't be impacted at all. ELv2 allows you to use the software internally, and you may continue to use the default distribution of Apollo Federation, including Apollo Gateway, Apollo Router Core and related Federation libraries for free. Restrictions only apply if you plan to offer a routing service to third parties or remove any licensing key code. To access our Enterprise plan, you will need a subscription.

I'm building a federated graph for my business. How does ELv2 affect me?

You may freely use Apollo Federation, including Apollo Gateway, Apollo Router Core and related Federation libraries inside your SaaS or self-managed application, and redistribute it with your application, provided you follow the three limitations outlined above.

I'm customizing the Apollo Federation libraries, Apollo Gateway or Apollo Router Core inside my application. How does ELv2 affect me?

You can make any modifications to the Apollo Federation packages (such as the router, gateway, or query planner), subject to only the three limitations summarized above. If you want to share those modifications with us, please see our contributing guide. If you have any questions, please reach out to us at [email protected].

Can I extend or modify the Gateway or Router by creating plugins?

Yes, absolutely.

Can I distribute a modified Gateway or Router?

Yes, absolutely. You just need to adhere to the three restrictions summarized above.

Am I required to release the source code to my gateway extensions?

No. Unlike GPL-style licenses, ELv2 does not require that you make your source code available. You just need to follow the three restrictions.

I contribute to Apollo Federation. How does ELv2 affect me?

There are no changes for contributors under ELv2. Thank you for your contributions to Apollo! If you're interested in contributing to any of our projects, please read our contributing guide.

Will Apollo continue to provide open-source software?

Absolutely! Open-source software is at the heart of what we do. We're grateful for the Apollo community and all your contributions. We are committed to developing our MIT-licensed projects you know and love, including Rover, Apollo Client, and Apollo Server, as well as pioneering new open-source graph technology. Relicensing Apollo Federation 2 to ELv2 helps us honor that commitment. It prevents bad actors from harming our community and protects our ability to build open-source software for years to come.

This limitation is intended to protect our software and brand by preventing folks from removing notice of the license, copyrights, or trademarks (such as the terms Apollo Federation and in-product logos). These notices communicate the license terms when redistributing the products. Open-source licenses such as MIT and Apache also require retention of copyright and permission notices in software copies, so this concept is not unique to ELv2.

What are some examples of providing the software to third parties as a hosted or managed service?

Using Apollo Federation to serve all traffic to my SaaS product

Yes, permitted.

Running a Gateway or Router that includes proprietary code, such as a plugin

Yes, permitted. There is no requirement to distribute or open-source your code.

Distributing a modified Gateway or Router that includes proprietary code as a product, like a console

Yes, permitted. Unlike GPL or SSPL, ELv2 is not copyleft. Your code remains closed.

Providing a public graph API in my SaaS product to third parties

Yes, permitted because you do not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the software.

Providing Apollo Federation as a service, where customers have direct access to substantial portions of Apollo Federation, including Apollo Gateway, Apollo Router Core or Federation libraries

This use is not permitted under the new license. If you have questions about your specific scenario, please reach out to us at [email protected].


File: src/content/basics/resources/faq.mdx


title: GraphQL FAQ

This article answers common questions about GraphQL, organized by phases in the GraphQL adoption timeline.

1. Learning GraphQL

You're just getting started with GraphQL. You're learning about syntax, running queries, schemas, and how to connect your existing services to your GraphQL layer.

What is GraphQL?

GraphQL is a language for querying data. Unlike most query languages (such as SQL), you don't use GraphQL to query a particular type of data store (such as a MySQL database). Instead, you use GraphQL to query data from any number of different sources.

Check out graphql.com to learn more about the basics of GraphQL.

With GraphQL, a client (such as a web app) doesn't need to know which data store contains the information it needs. Instead, clients send queries to your GraphQL server (usually over HTTP), which then fetches data from the appropriate data stores.

Here's an example query:

graphql
# Fetches a list of Book objects, each with a title and author
query GetBooks {
  books {
    title
    author
  }
}

Your GraphQL server defines a strongly typed schema that describes the data that clients can query for. Clients execute queries that conform to this schema's structure.

Here's an example GraphQL schema that supports the example query above:

graphql title="schema.graphql"
type Book {
  title: String
  author: String
  isbn: String
}

# The root fields of a query are always fields of the special
# Query type. These root fields are also called "entry points"
# into your schema.
type Query {
  # Returns a list of Book objects
  books: [Book]
}

Notice that the example query above doesn't fetch the isbn field that's defined here. It doesn't need to! GraphQL enables clients to query for exactly the fields they need, with no overhead.

Your GraphQL server uses a collection of special functions called resolvers that each know how to populate data for a particular schema field by communicating with different data sources (databases, REST APIs, etc.). When a query is fully resolved, your server responds to the client with the result, which matches the query's structure:

json
{
  "data": {
    "books": [
      {
        "title": "The Awakening",
        "author": "Kate Chopin"
      },
      {
        "title": "City of Glass",
        "author": "Paul Auster"
      }
    ]
  }
}

Why use GraphQL?

GraphQL can improve nearly every area of development: from improving developer experience with quality tooling to improving client performance by reducing bundle sizes. Read more about the benefits of GraphQL.

Where can I learn GraphQL?

Apollo's learning platform, Odyssey, provides practical, hands-on courses that help you learn GraphQL with Apollo technologies.

This documentation also includes getting-started content for each platform component:

For an introduction to core GraphQL concepts, check out graphql.org.

For technical GraphQL content from Apollo developer advocates and the larger GraphQL community, check out the Apollo blog.

How can I host my GraphQL server online?

GraphQL servers created with Apollo Server can be deployed to any environment that supports Node.js projects can be deployed. Apollo Server can also integrate with serverless deployment environments such as AWS Lambda.

There are deployment guides available for:

How do I connect my client app to my schema?

The Apollo platform has tools available to connect almost any kind of client to your schema:

For Apollo Client projects, there are also many view-layer integrations to make querying GraphQL schemas easier in React, Vue, and Angular.

2. Building a proof of concept

You understand how GraphQL works and the benefits it offers. You're trying to create a proof of concept for your project or company to test GraphQL's viability in production.

Which language should I use for my GraphQL server?

There are GraphQL server tools available for most popular languages, but we recommend using Apollo Server (Node.js) because of the ecosystem of tools developed for GraphQL in JavaScript. Node servers can also be run nearly anywhere, including on the edge.

How do I wrap existing APIs?

One of the best things about GraphQL is that it works excellently with existing APIs. It's possible to connect any number of existing services to your schema.

The most common source is a REST API. The RESTDataSource class integrates with Apollo Server to simplify fetching and caching for existing REST APIs.

However, you can connect any backend to a schema. Resolvers can do anything, including fetch data from an SDK or ORM.

How do I design the schema?

Schemas should be designed with the needs of the client in mind. Rather than modeling queries and types after the underlying services, they should be designed to make querying as easy as possible. GraphQL's resolver structure makes it possible to allow this flexibility without many performance consequences. For more, see Query-driven schema design.

How do I discover and reproduce errors?

As with any service, it's important to track errors and their causes. Many kinds of errors can occur in a GraphQL implementation. Some of these include service errors, where the schema can't access underlying data sources, and user errors, where a user enters invalid information in a query or mutation.

GraphQL is resilient to some of these errors. Because the schema is strongly typed, you can restrict what types of data users can provide as input, along with what types your resolvers can return. This type system catches many errors and requires no manual checks.

For errors not prevented by the type system, it's helpful to know what exact queries were made, and with what variables. GraphOS Studio is a tool that does exactly this. It can help discover and reproduce errors by showing the exact conditions in which the error occurred.

3. Moving a feature to GraphQL

You've decided to use GraphQL in production. You don't want to immediately refactor the APIs or apps. You want to move a single feature over to GraphQL to learn how to use it and monitor it in production.

How should the transition to GraphQL happen?

As with any large change, the adoption of GraphQL should be incremental. GraphQL allows teams to leave existing services as they are and build convenient gateways on top of them.

Who owns the schema design?

GraphQL schemas work best when their design is collaborated on by combination of backend implementers and frontend consumers. It's tempting to design a schema to mirror underlying API structures or database tables, but this can reduce the usefulness of GraphQL.

How do I set up authentication/authorization for my GraphQL schema?

Authentication and authorization are important topics to discuss with any API. GraphQL provides a granular approach to handling these topics. But don't worry, if an API being consumed by GraphQL already has authorization built-in, it may be possible to ignore it completely.

How can I secure my schema from malicious or expensive queries?

Public APIs of any kind need some kind of safeguards against malicious queries. Since GraphQL allows for recursive queries, it wouldn't be hard to create a query that is overly complicated and acts as a DoS attack, even by accident. There are multiple ways to prevent something like this from happening, from complexity limiting to query depth limiting. Read the guide on security to learn more.

What kinds of cache should I set up?

GraphQL can be cached in multiple places.

On the client, caches can prevent multiple queries from being called when data is already available locally. Client caches for GraphQL have one significant advantage over REST client caches: they can handle queries that have never been made. This is possible because of how GraphQL responses are normalized and stored.

For example, if a client requests a list of movies, each movie is cached separately on the client. Later, if the client requests a single movie in a different query and the needed movie is in the cache, the request doesn't have to use the network. This normalized cache is a part of apollo-client by default.

You can also set up server-side caching, including whole-query caching, partial-query caching, and cache backed by a CDN. These can lower response times and make your GraphQL server as performant as possible.

Whole-query and CDN caches are most useful when an API handles multiple identical queries. This commonly happens with public data, like content on pages of a site. Regardless of whether the API is used for public data or not, these caches almost always provide large performance benefits and are highly recommended. See Server-side caching to learn about whole-query and CDN caching with Apollo Server.

Partial query caching can be achieved by caching the responses from underlying services with something like Redis or Memcache. With this strategy, even if two queries look completely different from one another, if there is any duplication of data fetched, those results can be shared, preventing unnecessary traffic. The RESTDataSource does this automatically if the appropriate cache-control headers are present in REST responses.

How can I monitor the health of my GraphQL schema?

Many apps and sites are powered almost completely by an API such as a GraphQL schema, so it's important to make sure the API is stable at all times. Indicators of an unhealthy service include long response times, high resource usage, and unusual traffic patterns.

GraphOS Studio is a great tool to track many of these things. It allows close inspection of fields to make it easy to see both total response times as well as how long each field took to execute.

GraphOS Studio also has some integrations to make monitoring easier. Notifications can deliver daily reports to give teams a quick overview of the health of their schema. The enterprise Datadog integration works with existing Datadog accounts to help teams track schema performance.

4. Moving a product to GraphQL

You have a good understanding of how to write, deploy, and monitor GraphQL in production. You are looking to scale GraphQL features to your entire product line.

How do I organize schema code to scale for a larger project?

Keeping all schema code together makes sense for smaller projects, but once a project reaches a certain size, or has many people working on it, managing conflicts in the same file and code navigation can get difficult. Splitting types and resolvers up into smaller files can make this process much easier. Read this blog post to learn more.

How can I test my client?

Apollo Client comes with everything needed to test a client app that makes queries to a GraphQL server. For details, see Testing React components.

How can I safely make changes to my schema?

Schemas naturally evolve over time. GraphQL schemas are more resilient to change than other APIs, but there are still occasions where breaking changes are necessary to support new functionality. This section explains in more detail which kinds of changes are always safe to make, and which kinds might break existing clients.

The schema checks feature of Apollo GraphOS helps you identify potentially breaking schema changes before you make them.


File: src/content/basics/resources/glossary.mdx


title: Apollo Glossary subtitle: Familiarize yourself with Apollo and GraphQL terminology

import GlossaryPage from '../../../components/GlossaryPage';

As you familiarize yourself with GraphQL and explore what Apollo has to offer, you might encounter some unfamiliar terms along the way. To help you on your journey, we've defined some of the most common Apollo and GraphQL vocabulary in this glossary.

If you want to request a new term or a change to an existing term, please use the glossary request form.


File: src/content/basics/resources/product-launch-stages.mdx


title: Apollo launch stages

Product launch stages

All launches of Apollo products, features, and open-source releases use two launch stages: preview and general availability.

Preview

Product and feature previews are usually announced publicly and represent a near-complete version of associated functionality. However, previews are not officially supported with any SLA, and breaking API changes are possible between incremental versions of a preview.

A preview might still contain bugs or undergo iteration. You're encouraged to try previews in test environments to familiarize yourself with upcoming functionality before it reaches general availability.

General availability

A generally available product or feature has been deemed ready for use in a production environment and is officially supported by Apollo. Its documentation is considered sufficient to support widespread adoption.

Open-source pre-releases

Apollo open-source projects might provide pre-releases for early access:

Alpha / beta

An alpha or beta is in volatile, active development. The version might not be feature-complete, and breaking API changes are possible between incremental versions of the alpha or beta.

Alphas and betas help Apollo gather feedback and issues from community members and customers who are enthusiastic early adopters.

Release candidate

A release candidate (RC) is considered potentially viable for general availability. Minor bugs might still be present, and documentation for the release might be incomplete.

You're encouraged to test out RC versions to help Apollo identify any remaining issues.

Experimental features

At Apollo, we believe in developing and iterating in the open. Experimental features are targeted at developers who want to adopt advanced, cutting-edge functionality. Experimental features might not be complete, they might have breaking changes at any time, and they might be removed from a product or an incremental version of an open-source release without notice.

Stages for discontinuing support

When support is ending for a generally available Apollo product, feature, or open-source release, it first becomes deprecated, then eventually end-of-life.

Deprecated

A deprecated product, feature, or open-source release is still supported by Apollo. It continues to receive security patches and updates to address major regressions. An end-of-life date is provided alongside the deprecation, after which support ends.

Avoid relying on deprecated releases whenever possible. Consider upgrading to the latest generally available release to continue receiving new features and functionality.

End-of-life

Products, features, and open-source releases that reach end-of-life are no longer supported or maintained by Apollo. They no longer receive updates, security patches, or remediation for regressions. There is no commitment from Apollo to release further versions and no guarantee that the most recent version will continue to work. End-of-life products and features are no longer generally available.

End-of-life releases published to a package registry aren't removed from that registry. This means you can still install end-of-life versions past the end-of-life date (though Apollo strongly recommends against this).

Do not run end-of-life open-source releases in production. Upgrade to the latest generally available release as soon as possible to ensure you continue receiving security patches, bug fixes, new features, and compatibility with GraphOS features.


File: src/content/community/blog-post-contributions.md


title: Blog Post Contributions

We love community contributions to the Apollo Blog! If you're as excited about the data graph as we are and would like to teach the community, share your unique Apollo experience, or show off something cool you've built with Apollo, we're here for you.

Contributing to the blog

If you'd like to contribute to the Apollo Blog, we ask that you first submit your blog post idea using our Blog Post Proposal form. Read on for more information on how to get your blog post on the Apollo Blog.

Blog post proposal process

  1. Submit the Blog Post Proposal form.
  2. An Apollo team member will get back to you within a week and let you know if the post was accepted after reviewing your proposal.

Accepted posts

If we've accepted your post, we'll work with you to turn your idea into a draft and then into an excellent blog post that the community can benefit from!

Posts not accepted

If we didn't accept your post, no worries. We'll provide you with feedback or other ways that we can turn your post into something that will be useful to the community. Either way, we'll help you!

Content guidelines

Here are some tips for writing awesome content that helps the community.

Content we love

Types of blog posts we love to read:

  • “How to” guides, recipes, or tutorials on how to address problems you've solved with Apollo (here's an example, "Apollo Client [React] - How to Query on Click")
  • Stories about how Apollo helped you overcome different challenges on work and personal projects
  • Something cool you built with Apollo
  • Showcasing a tool, fix, or other content you or someone else has contributed to Apollo's open source community
  • Guidance and resources for learning Apollo, GraphQL, best practices, architecture, different tools/integrations, and other Apollo-related content.
  • Any other topics that you think would be valuable to people learning about or working with Apollo

We're open to all kinds of topics as long as it relates to Apollo in some way. We love posts of all reading levels (beginner to intermediate, to advanced). If you're stumped, we especially like posts that mix Apollo with the following topics:

  • TypeScript
  • GraphQL best practices
  • Caching
  • React.js
  • Authentication & authorization
  • Error handling
  • Frontend development
  • Server-side development
  • Scaling GraphQL
  • Schema design

Content to avoid

  • Docs content. Some content is better found in the Apollo docs guides and tutorials, as it can be found in a section for related content and not buried under pages of other paginated blog posts.

  • Promotional content. Please don't submit content to the Apollo blog solely to promote a product, yourself, or link-building.

    • Here's what you can do instead: If you have a product or project you want to share on the Apollo blog, focus on practical information, and make sure there's a clear relationship with Apollo or Apollo-adjacent topics. You could write a step by step guide to using your product with Apollo. You could write a case study highlighting the direct impact Apollo had on your awesome project and offer helpful tips for others to recreate your success.
  • Content that doesn't seem to have a clear benefit for Apollo users and/or the Apollo community. For example, if you're writing about a use-case or integration that's extremely niche or unique to specific conditions that are uncommon outside of your organization, the Apollo blog might not be the best place for your content. Likewise, if your blog post doesn't seem to have any direct relationship with Apollo (or an interesting indirect relationship with Apollo), then it may be more appropriate for a personal blog or another community blog.

These are all guidelines. If you believe something is valuable to the Apollo community, please do submit it to us- we'd love to hear from you!


File: src/content/community/code-of-conduct.md


title: Apollo Code of Conduct

Apollo code of conduct

If you see a code of conduct violation, follow these steps:

  • Let the person know that what they did is not appropriate and ask them to stop and/or edit their message(s) if online.
  • That person should immediately stop the behavior and correct the issue.
  • If this doesn't happen, or if you're uncomfortable speaking up, contact organizers by emailing [email protected].
  • As soon as available, an organizer will respond, identify themselves, and take further action (see below), starting with a warning, then temporary deactivation, then long-term deactivation.
  • When reporting, please include any relevant details, links, screenshots, context, or other information that may be used to better understand and resolve the situation.
  • The Admin team will prioritize the well-being and comfort of those affected negatively by the violation over the comfort of the violator. This may include the violator being removed from online or in-person spaces until those affected say they would feel safe with the person returning.

Our goal

This community is dedicated to providing a harassment-free experience for everyone. We do not tolerate harassment of participants in any form.

Applicability and scope

This code of conduct applies to all this community's spaces, including public channels, private channels and direct messages, both online and off. Anyone who violates this code of conduct may be sanctioned or expelled from these spaces at the discretion of the administrators.

Toward a welcoming and safe environment

We hope to create an environment in which diverse individuals can collaborate and interact in a positive and affirming way. Examples of behavior that contributes to creating this sort of environment include:

  • Using welcoming and inclusive language
  • Being respectful of differing viewpoints and experiences
  • Gracefully accepting constructive criticism
  • Focusing on what is best for the overall community
  • Showing empathy toward other community members

Anti-harassment statement

This community will not tolerate harassment of any kind. Examples of harassment include:

  • Offensive comments, usernames, and emoji related to gender, gender identity and expression, sexual orientation, disability, mental illness, neuro(a)typicality, physical appearance, pregnancy status, veteran status, political affiliation, marital status, body size, age, race, national origin, ethnic origin, nationality, immigration status, language, religion or lack thereof, or other identity markers. This includes anti-Indigenous/Nativeness and anti-Blackness.
  • Unwelcome comments regarding a person's lifestyle choices and practices, including those related to food, health, parenting, relationships, drugs, and employment.
  • Deliberate misgendering, using inappropriate pronouns, or use of "dead" or rejected names.
  • Gratuitous or off-topic sexual images or behavior in spaces where they're not appropriate.
  • Physical contact and simulated physical contact (for example, textual descriptions like "hug" or "back rub") without consent or after a request to stop.
  • Threats of violence.
  • Incitement of violence toward any individual or group, including encouraging a person to commit suicide or to engage in self-harm.
  • Deliberate intimidation.
  • Stalking or following - online or in the physical world.
  • Harassing photography or recording, including logging online activity for harassment purposes.
  • Sustained disruption of discussion.
  • Unwelcome sexual attention.
  • Patterns of inappropriate social contact, such as requesting/assuming inappropriate levels of intimacy with others.
  • Continued one-on-one communication after requests to cease.
  • Deliberate "outing" of any aspect of a person's identity without their consent except as necessary to protect vulnerable people from intentional abuse.
  • Publication of non-harassing private communication.
  • Jokes that resemble the above, such as "hipster racism," still count as harassment even if meant satirically or ironically.

If you have questions or concerns about these issues please feel free to message an admin or ask for an opportunity to explore the issue with a moderator and volunteers.

Reporting

If you are being harassed by a member of our community, notice that someone else is being harassed, or have any other concerns, please contact the administrators via [email protected]. If the person who is harassing you is on the admin team, they will not be involved in handling or resolving the incident.

The admin team will respond to any complaint as promptly as possible we can. If you do not get a timely response (for example, if no admins are currently online) then please put your personal safety and well-being first, and consider logging out and/or contacting the admins by email at [email protected].

This code of conduct applies to our community's spaces, but if you are being harassed by a member of our community outside our spaces, we still want to know about it. We will take all good-faith reports of harassment by our members, especially the administrators, seriously. This includes harassment outside our spaces and harassment that took place at any point in time. The abuse team reserves the right to exclude people from the community based on their past behavior, including behavior outside of our spaces and behavior toward people who are not in this community.

In order to protect volunteers from abuse and burnout, we reserve the right to reject any report we believe to have been made in bad faith. Reports intended to silence legitimate criticism may be deleted without response.

Enforcement process

Every code of conduct violation report will be treated with seriousness and care. If a member's immediate safety and security is threatened, an individual admin may take any action that they deem appropriate, up to and including temporarily banning the offender from the community. In less urgent situations, at least two admins will discuss the offense and mutually arrive at a suitable response, which will be shared with the offender privately. Whatever the resolution that they decide upon, the decision of the admins involved in a violation case will be considered final.

We will respect confidentiality requests for the purpose of protecting victims of abuse. At our discretion, we may publicly name a person about whom we've received harassment complaints, or privately warn third parties about them, if we believe that doing so will increase the safety of our members or the general public. We will not name harassment victims without their affirmative consent.

Apollo prioritizes marginalized people's safety over privileged people's comfort. The administrators will not act on complaints regarding:

  • “Reverse”-isms, including “reverse racism,” “reverse sexism,” and “cisphobia”
  • Reasonable communication of boundaries, such as “leave me alone,” “go away,” or “I'm not discussing this with you.”
  • Communicating in a “tone” you don't find congenial
  • Criticizing racist, sexist, cissexist, or otherwise oppressive behavior or assumptions
  • The examples listed above are not against the Code of Conduct.

Consequences

Participants asked to stop any harassing behavior are expected to comply immediately. If a participant engages in harassing behavior, the administrators may take any action they deem appropriate, up to and including expulsion from the community and identification of the participant as a harasser to other members. At the discretion of the admins, or by request, one or more of the parties involved may request to discuss the violation and how to avoid similar situations in the future.

Acknowledgements

This Code of Conduct is adapted from the Community Covenant (http://community-covenant.net), version 1.0, available at http://community-covenant.net/version/1/0/. The Community Covenant is an open source effort and is built on codes of conduct that came before it, including the Contributor Covenant (http://contributor-covenant.org/) and the LGBTQ in Tech community code of conduct (http://lgbtq.technology/coc.html).

This CoC also includes material adapted from the LGBTQ in Tech community code of conduct (http://lgbtq.technology/coc.html) beyond what the community covenant includes.

License

Community Covenant by Coraline Ada Ehmke is licensed under a Creative Commons Attribution 4.0 International License (http://creativecommons.org/licenses/by/4.0/). Based on a work at http://community-covenant.net/.


File: src/content/community/config.json

{
"title": "Community",
"description": "Get involved the Apollo Community",
"sidebar": {
"Get Involved": "/",
"Contributing Guide": "/contributing",
"Blog Post Contributions": "/blog-post-contributions",
"Apollo Code of Conduct": "/code-of-conduct",
"GraphQL Events": "/graphql-events",
"Streaming at Apollo": "/streaming-at-apollo"
}
}


File: src/content/community/contributing.md


title: Contributing Guide

Excited about Apollo and want to make it better? We're excited too. Read below to learn about different ways to contribute to the project.

Issues

Reporting bugs

If you encounter a bug, please file an issue on GitHub via the repository of the sub-project you think contains the bug. If an issue you have is already reported, please add additional information or add a 👍 reaction to indicate your agreement.

While we will try to be as helpful as we can regardless, please include the following to maximize the chances of a quick fix:

  1. Intended outcome: What you were trying to accomplish when the bug occurred, and as much code as possible related to the source of the problem.
  2. Actual outcome: A description of what actually happened, including a screenshot or copy-paste of any related error messages, logs, or other output that might be related. Places to look for information include your browser console, server console, and network logs. Please avoid non-specific phrases like “didn't work” or “broke”.
  3. Reproduction: A minimal reproduction of the issue that we can run. This is ideally in the form of a small application we can clone from GitHub, or a failing test sent in the form of a PR. The reproduction should contain as little code as possible to demonstrate the bug.

Creating a good reproduction really helps contributors investigate and resolve your issue quickly. In many cases, the act of creating a minimal reproduction illuminates that the source of the bug was somewhere outside the library in question, saving time and effort for everyone.

A good starting point for building reproductions are the "hello world" examples on the developer home page:

Suggesting features

Most of the features in Apollo were suggested by the community at some point in time. We welcome any ideas about how to make our project better for your use case. Unless there is overwhelming demand for a feature, it might not get implemented immediately, but please include as much information as possible that will help people have a discussion about your proposal:

  1. Use case: What are you trying to accomplish, in specific terms? Often, there might already be a good way to do what you need and a new feature is unnecessary, but it's hard to know without information about the specific use case.
  2. Could this be a plugin? In many cases, a feature might be too niche to be included in the core of a library, and is better implemented as a companion package. If there isn't a way to extend the library to do what you want, could we add additional plugin APIs? It's important to make the case for why a feature should be part of the core capability of the library.
  3. Is there a workaround? Is this a more convenient way to do something that is already possible, or is there some blocker that makes a workaround unfeasible?

Feature requests will be labeled as such, and we encourage using GitHub issues as a place to discuss new features and possible implementation designs. Please refrain from submitting a pull request to implement a proposed feature until there is consensus that it should be included. This way, you can avoid putting in work that can't be merged in.

Once there is a consensus on the need for a new feature, proceed as listed below under “Big PRs”.

Small PRs

If there is a small change to be made, please feel free to open a PR right away with the fix or improvement. For this category of pull requests, there is no need to write a design first.

Documentation fixes

Improving the documentation, examples, and other open source content can be the easiest way to contribute to the library. If you see a piece of content that can be better, open a PR with an improvement, no matter how small! If you would like to suggest a big change or major rewrite, we'd love to hear your ideas but please open an issue for discussion before writing the PR.

Small bug fixes

For a small bug fix change (less than 20 lines of code changed), feel free to open a pull request. We'll try to merge it as fast as possible and ideally publish a new release on the same day. The only requirement is, make sure you also add a test that verifies the bug you are trying to fix.

Big PRs

This includes:

  • Big bug fixes
  • New features

For significant changes to a repository, it's important to settle on a design before starting on the implementation. This way, we can make sure that major improvements get the care and attention they deserve. Since big changes can be risky and might not always get merged, it's good to reduce the amount of possible wasted effort by agreeing on an implementation design/plan first.

  1. Open an issue. Open an issue about your bug or feature, as described above.
  2. Reach consensus. Some contributors and community members should reach an agreement that this feature or bug is important, and that someone should work on implementing or fixing it.
  3. Agree on intended behavior. On the issue, reach an agreement about the desired behavior. In the case of a bug fix, it should be clear what it means for the bug to be fixed, and in the case of a feature, it should be clear what it will be like for developers to use the new feature.
  4. Agree on implementation plan. Write a plan for how this feature or bug fix should be implemented. What modules need to be added or rewritten? Should this be one pull request or multiple incremental improvements? Who is going to do each part?
  5. Submit PR. In the case where multiple dependent patches need to be made to implement the change, only submit one at a time. Otherwise, the others might get stale while the first is reviewed and merged. Make sure to avoid “while we're here” type changes - if something isn't relevant to the improvement at hand, it should be in a separate PR; this especially includes code style changes of unrelated code.
  6. Review. At least one core contributor should sign off on the change before it's merged. Look at the “code review” section below to learn about factors are important in the code review. If you want to expedite the code being merged, try to review your own code first!
  7. Merge and release!

Code review guidelines

It's important that every piece of code in Apollo packages is reviewed by at least one core contributor familiar with that codebase. Here are some things to look for:

  1. Required CI checks pass. If the tests don't pass, there is no need to review the PR until they do.
  2. Simplicity. Is this the simplest way to achieve the intended goal? If there are too many files, redundant functions, or complex lines of code, suggest a simpler way to do the same thing. In particular, avoid implementing an overly general solution when a simple, small, and pragmatic fix will do.
  3. Testing. Do the tests ensure this code won't break when other stuff changes around it? When it does break, will the tests added help us identify which part of the library has the problem? Did we cover an appropriate set of edge cases? Look at the test coverage report if there is one. Are all significant code paths in the new code exercised at least once?
  4. No unnecessary changes. PRs shouldn't come with random formatting changes, especially in unrelated parts of the code. If there is some refactoring that needs to be done, it should be in a separate PR from a bug fix or feature, if possible.
  5. Code has appropriate comments. Complicated logic should be commented, or written in a clear “self-documenting” way.
  6. Idiomatic use of the language. In TypeScript, make sure the typings are specific and correct. In ES2015, make sure to use imports rather than require, and const instead of var, etc. Ideally a linter enforces much of this, but use your common sense and follow the style of the surrounding code.

File: src/content/community/graphql-events.md


title: GraphQL Events

The team at Apollo loves to speak at events, help community members looking to speak about GraphQL or Apollo, and organize quality events. Read on to see how you can get involved!

Bookmark our events hub

Apollo events is where you can find all our upcoming events and webinars as well as any recordings from our past events. If you want to keep up to date on GraphQL best practices, Apollo open source updates, new product features, and more, make sure to check the events regularly!

Give a talk

Whether you're gearing up to give a GraphQL or Apollo talk at a local meetup or a large industry event, we want to help spread the word and set you up with the resources to feel prepared. Let us know on Twitter about events you're submitting to, when you're planning to speak, or when your talk videos have been published!

Meetups

There over 50 meetups around the world featuring talks by and for GraphQL developers. Find the one nearest you or get in touch for support in organizing one yourself!

GraphQL Summit

We organize GraphQL Summit, the first yearly conference dedicated to GraphQL developers. Summit is the best place to learn how companies are using GraphQL in production, check out the future of the technology, and meet the friendly community working to support and advance it. We're always looking for speakers, so reach out to the Summit team if you're interested in presenting in the future!


File: src/content/community/index.md


title: Get Involved

Welcome! The Apollo community is made up of developers around the world who are building awesome things with GraphQL. In this section, you can learn how to get help with Apollo and GraphQL, contribute to Apollo projects, and attend events and talks organized by the community.

Join the community

Come chat with Apollo team members, contributors, and developers on the Apollo forums. It's a great place to get help using Apollo and discuss the latest in the GraphQL community.

To keep up to date on all things Apollo, you can follow us on Twitter and check out the Apollo blog.

Contribute to Apollo

The Apollo project lives on GitHub, and is made up of a diverse set of tools for implementing GraphQL, written and maintained by contributors around the world. We'd love your help!

Here are some ways you can get involved with the project:

  • Report an issue
  • Submit a pull request
  • Update or write documentation
  • Write a blog post
  • Give a conference talk
  • Organize a meetup

To get started contributing, first read our Code of Conduct and Contributing Guide. We can't wait to work with you!

Share your GraphQL story

We love to hear stories about what people building with Apollo or GraphQL. Email us at [email protected] to let us know if you're speaking at an event or have an interesting experience to share. We'll help get the word out!

Write a blog post

Have a great idea for a blog post to share on the Apollo Blog? Check out the Blog Post Contributions page.

Attend an event

You can catch the Apollo team and contributors IRL at conferences and meetups around the world. Follow us on Twitter to hear where we'll be next.

If you're based in the SF Bay Area, or just pass through sometimes, join our GraphQL San Francisco meetup to get updated when we schedule a new one.

Every year we organize GraphQL Summit, the first and largest conference for GraphQL developers, in San Francisco. Watch videos from past GraphQL Summits on our YouTube channel!


File: src/content/community/streaming-at-apollo.mdx


title: Streaming at Apollo

We're always looking for ways to engage with the Apollo community, and live streaming is an excellent way for us to do just that. If you're interested in how you can participate, or want to know when and what we stream, then read on!

Where we stream

Currently, we stream on Twitch.

Want to see us stream on a particular platform? Let us know on social media.

What we stream

Each Apollo stream presents one of the following shows:

  • Launch Pad: This show is about building apps from start to finish! Each series will use a different technology stack to build functional apps that take advantage of the Apollo eco-system.

  • Mission Briefing: This show is about tools, features, services, and general knowledge content coming from inside and outside Apollo.

  • Orbit: This show is about what's going on in the GraphQL/Apollo community such as events, tools, products, and content related to GraphQL.

If you think we're missing something, we'd love to hear your ideas.

Schedule

If you want to stay up to date on when we'll be streaming next, you can subscribe to our calendar or check the schedule panel on Twitch.

Join us

Have an idea you think would make for an amazing stream? Fill out this form and we'll get in touch.


File: src/content/graphos/basics/api-keys.mdx


title: API Keys subtitle: Use graph and personal API keys to authenticate requests

Every system that communicates with Apollo GraphOS must use an API key to do so. GraphOS Studio enables you to create and manage two types of API keys: graph API keys and personal API keys.

Any system that isn't running as part of your local development setup should always use a graph API key.

Graph API keys

A graph API key provides access to interacting with a single graph in GraphOS.

Create a unique graph API key for each non-development system that communicates with GraphOS. Doing so enables you to revoke access to a single system without affecting others.

Setting permissions

Unless you have an Enterprise plan, every graph API key provides full access to its associated graph.

If you have an Enterprise plan, you can assign a role to each graph API key you create. If you do, the API key's permissions are limited to that role's permissions.

You can't change a graph API key's role after it's created. Instead, create a new key with the desired role.

Personal API keys

A personal API key provides partial access to every graph in every organization you belong to. Specifically, it has the same permissions that your user account has in each of those organizations.

Personal API keys are useful for local development tools (like the Rover CLI and the Apollo VS Code extension) to load schemas and other data from GraphOS.


File: src/content/graphos/basics/config.json

{
"title": "Graph Essentials",
"algoliaFilters": [
[
"docset:graphos",
"docset:graphos/delivery",
"docset:graphos/metrics",
"docset:graphos/org",
"docset:graphos/explorer",
"docset:graphos/enterprise"
],
[
"docset:rover",
"docset:router",
"docset:federation"
]
],
"sidebar": {
"Intro to GraphOS": "/",
"Graphs and Variants": "/graphs",
"Routing": "/routing",
"Get Started": {
"Cloud Setup": "/quickstart/cloud",
"Self-Hosted Setup": [
"/quickstart/self-hosted",
[
"enterprise"
]
],
"Next Steps": "/quickstart/next-steps"
},
"Graph Development": {
"Creating a New Subgraph": "/graphs/creating-a-subgraph",
"Local Subgraph Development": "/graphs/local-development",
"Updating Your Graph": "/graphs/updating"
},
"GraphOS Studio Features": {
"Graph Exploration": "/graphs/studio-features",
"Supergraph-Specific Features": "/graphs/federated-graphs"
},
"Graph Administration": {
"API Keys": "/api-keys",
"Graph Management": "/graphs/management"
},
"Graph Security": {
"Securing Subgraphs": "/graphs/securing-a-subgraph",
"Safelisting with Persisted Queries": [
"/operations/persisted-queries",
[
"enterprise"
]
]
},
"Client Operations": {
"Using @defer": "/operations/defer",
"GraphQL Subscriptions": [
"/operations/subscriptions",
[
"preview"
]
]
},
"GraphOS Interfaces": {
"Studio UI": "https://studio.apollographql.com",
"Rover CLI": "https://apollographql.com/docs/rover/",
"Platform API": "/platform-api"
},
"Platform Data Processing": {
"Data Privacy / GDPR": "/data-privacy",
"Sub-Processors": "/sub-processors"
}
}
}


File: src/content/graphos/basics/data-privacy.mdx


title: GraphOS Data Privacy and Compliance

This article describes which data is and is not sent to Apollo GraphOS by other Apollo tools and libraries.

Our top priority is ensuring the privacy and security of your data and your customers' data. No Apollo tool or library running in your environment sends any data to GraphOS unless you configure it to do so. Features that potentially send highly sensitive data require additional opt-in.

Does GraphOS store operation result data returned by my graph?

No. Your graph's operation results never even reach any Apollo-managed service, with one important exception: cloud supergraphs use a GraphOS Router, which passes results directly from your subgraphs to requesting clients, without logging, persisting, or sending those results to any other system (other data like operation metrics are persisted).

Which tools send data to GraphOS?

The GraphOS Router, Apollo Server, the Rover CLI, and the legacy Apollo CLI have opt-in features that send data to GraphOS.

The Rover CLI also collects anonymous usage data by default. You can turn this off.

The Apollo Kotlin IDE plugin also collects anonymous usage data by default. You can turn this off.

If you have a cloud supergraph, its router is hosted and managed by GraphOS, and it automatically enables metrics reporting. Learn about data collection for cloud supergraphs.

Apollo Client libraries do not send data to GraphOS.

Where is data sent?

All data sent to GraphOS is sent to an endpoint with one of the following base URLs:

Current URLs

Base URL Used by
https://usage-reporting.api.apollographql.com Metrics reporting from the GraphOS Router (v0.1.0+), Apollo Server (v2.18.0+), and third-party API servers
https://rover.apollo.dev The Rover CLI—all commands if telemetry is enabled, rover supergraph compose when fetching new plugin versions, all rover template commands, and once per day to check for version updates
https://api.apollographql.com/graphql All Rover CLI (v0.6+) commands that communicate with GraphOS, along with all requests to the GraphOS Platform API
https://router.apollo.dev The GraphOS Router installer (all versions), along with GraphOS Router (v1.9.0+) telemetry when enabled
https://uplink.api.apollographql.com GraphOS Router (v0.1.0+) with managed federation and/or Enterprise features enabled, Apollo Server with Apollo Gateway (v0.34.0+) with managed federation
https://aws.uplink.api.apollographql.com GraphOS Router (v0.1.0+) with managed federation and/or Enterprise features enabled, Apollo Server with Apollo Gateway (v0.45.0+) with managed federation
https://persisted-queries.api.apollographql.com/ GraphOS Router (v1.25.0+) with GraphOS persisted queries enabled
https://aws.persisted-queries.api.apollographql.com/ GraphOS Router (v1.25.0+) with GraphOS persisted queries enabled
https://schema-reporting.api.apollographql.com Schema registration via schema reporting in Apollo Server (v2.18.0+) and third-party API servers
https://graphql.api.apollographql.com/api/graphql Anonymous usage data from the Apollo Kotlin IDE plugin

Active legacy URLs

Base URL Used by
https://engine-report.apollodata.com Metrics reporting from Apollo Server (v2.0-2.17.x)
https://edge-server-reporting.api.apollographql.com Schema registration via schema reporting in Apollo Server (v2.15.0-2.17.x)
https://engine-graphql.apollographql.com All legacy Apollo CLI (v2.30 and earlier) commands that communicate with GraphOS
https://storage.googleapis.com Apollo Server with Apollo Gateway (v0.15.1 and earlier) with managed federation, or with the operation registry plugin (v0.3.1 and earlier)
https://federation.api.apollographql.com Apollo Server with Apollo Gateway (v0.16.0-v0.33.0) with managed federation
https://storage-secrets.api.apollographql.com Apollo Server with Apollo Gateway (v0.16.0-v0.33.0) with managed federation, or with the operation registry plugin
https://operations.api.apollographql.com Apollo Server with the operation registry plugin (v0.4.1+)
https://graphql.api.apollographql.com All Rover CLI (prior to v0.6) commands and legacy Apollo CLI(v2.31+) commands that communicate with GraphOS

If your environment uses a corporate proxy or firewall, you might need to configure it to allow outbound traffic to these domains. Note that data might be sent to multiple endpoints in a given domain.

Which types of data do the GraphOS Router and Apollo Server send to GraphOS?

You can configure both the GraphOS Router and Apollo Server to report certain data to GraphOS for each operation resolved by these libraries. These types of data include:

  • Several fields besides data from every operation response

    • Neither the GraphOS Router nor Apollo Server ever sends the data field of an operation response to GraphOS.
  • The normalized query operation string for every executed operation

  • Trace data indicating the execution time for every resolver in the operation

  • The values of operation GraphQL variables and HTTP headers

These types of data are covered in the subsections below.

In addition, you can configure a standalone instance of Apollo Server to report its schema to GraphOS.

All data sent to GraphOS from both the GraphOS Router and Apollo Server is transmitted using HTTPS on port 443, and HTTP traffic on port 80 is turned off.

Operation response fields

Let's walk through the default behaviors of the GraphOS Router and Apollo Server when reporting fields in a typical GraphQL response:

json
// GraphQL Response
{
  "data": { ... },  // NEVER sent to GraphOS
  "errors": [ ... ] // Can be sent to GraphOS, used to report on errors for operations and fields.
}

`response.data`

As mentioned, the GraphOS Router and Apollo Server never send the contents of this field to GraphOS. The responses from your graph stay internal to your application.

`response.errors`

Both the GraphOS Router and Apollo Server can report certain error information to GraphOS, but the exact behavior varies:

The GraphOS Router

Currently, the GraphOS Router reports only which fields in an operation produced errors. Other error details (such as messages) are masked in reports to GraphOS.

You cannot currently configure the GraphOS Router to report any additional error details.

Apollo Server 4

By default, Apollo Server 4 reports only which fields in an operation produced errors.

You can configure Apollo Server 4 to provide additional error details (such as error messages and extensions). To do so, provide the sendErrors option to Apollo Server's usage reporting plugin.

Apollo Server 2 and 3

Apollo Server versions 2 and 3 are deprecated.

By default, Apollo Server versions 2 and 3 report all error details to GraphOS, including messages and extensions.

You can use the usage reporting plugin's rewriteError option to filter or transform errors before they're stored in GraphOS. Use this to strip sensitive data from errors or filter "safe" errors from Studio reports.

Query operation strings

The GraphOS Router and Apollo Server both report a normalized string representation of each query operation to GraphOS. By default, this normalization algorithm strips out string literals that are passed as arguments. However, we highly recommend that users do not include sensitive data (such as passwords or personally identifiable information) in operation strings. Instead, include this information in GraphQL variables, which you can send selectively.

If you enable enhanced operation signature normalization in the router, the operation signature includes the input object shapes while redacting any of the actual values. Learn more.

Operation traces

If you're using the GraphOS Router, your subgraphs can include operation trace data in each of their responses to the router. This data includes timing information for each resolver that contributed to the operation.

To check which subgraph libraries support federated traces, consult the FEDERATED TRACING entry in this table.

You can configure the GraphOS Router to include this trace data in its reports to GraphOS (learn how). By doing so, you can visualize the performance of your operations in GraphOS Studio, broken down by resolver.

If you're using a standalone instance of Apollo Server, you can also configure it to report operation traces to GraphOS.

GraphQL variable values

This section pertains to the values of variables that are included in GraphQL operations. The names of these variables are included in operation strings that are sent to GraphOS.

Apollo Server 2.7.0 and later

In Apollo Server 2.7.0 and later, none of an operation's GraphQL variable values are sent to GraphOS by default.

You can set a value for the usage reporting plugin's sendVariableValues option to specify a different strategy for reporting some or all variable values.

Apollo Server prior to 2.7.0

In versions of Apollo Server 2 prior to 2.7.0, all of an operation's GraphQL
variable values are sent to GraphOS by default.

If you're using an earlier version of Apollo Server, it's recommended that you update. If you can't update for whatever reason, you can use the privateVariables reporting option to specify the names of variables that should not be sent to GraphOS. You can also set this option to false to prevent all variables from being sent. This reporting option is deprecated and will not be available in future versions of Apollo Server.

GraphOS Router

By default, the GraphOS Router does not send an operation's GraphQL variable values to GraphOS.

To enable variable value reporting in the GraphOS Router, see this section.

HTTP headers

Regardless of your server configuration, GraphOS never collects the values
of the following HTTP headers, even if they're sent:

  • Authorization
  • Cookie
  • Set-Cookie

You can, however, configure reporting options for all other HTTP headers.

If you perform authorization in a header other than those listed above (such as X-My-API-Key), do not send that header to GraphOS.

Apollo Server 2.7.0 and later

In Apollo Server 2.7.0 and later, none of an operation's HTTP headers is sent to GraphOS by default.

You can set a value for the usage reporting plugin's sendHeaders option to specify a different strategy for reporting some or all your HTTP headers.

Apollo Server prior to 2.7.0

In versions of Apollo Server 2 prior to 2.7.0, all of an operation's HTTP headers (except the confidential headers listed above) are sent to GraphOS by default.

If you're using an earlier version of Apollo Server, it's recommended that you
update. If you can't update for whatever reason, you can use the privateHeaders reporting option to specify the names of variables that should not be sent to GraphOS. You can also set this option to false to prevent all headers from being sent. This reporting option is deprecated and will not be available in future versions of Apollo Server.

GraphOS Router

By default, the GraphOS Router does not send an operation's HTTP header values to GraphOS.

To enable header reporting in the GraphOS Router, see this section.

Which types of data are collected by a cloud supergraph?

A cloud supergraph uses a GraphOS Router to execute operations across one or more subgraphs hosted in your infrastructure:

mermaid
flowchart LR;
  clients(Clients);
  subgraph "GraphOS";
  router(["Router"]);
  end;
  subgraph "Your infrastructure";
  subgraphA[Subgraph A];
  subgraphB[Subgraph B]
  router --- subgraphA
  router --- subgraphB
  end;
  clients -.- router;
  class clients secondary;

Each instance of GraphOS Router runs in its own managed container. These instances use the same mechanisms to report operation metrics to GraphOS as a GraphOS Router or Apollo Router Core instance running in any other environment. The only difference is that metrics reporting is always enabled for a cloud supergraph's router.

GraphOS Routers do not persist or log any response data returned by your subgraphs. They only assemble this data into responses for requesting clients.

What data does GraphOS log about operations executed in the Explorer?

Only frontend usage metrics for improving the product. The GraphOS Studio Explorer enables you to build and execute operations against your graph. These operations are sent directly from your browser and do not pass through Apollo systems.

GDPR

Effective May 25, 2018, the General Data Protection Regulation (GDPR) expands European Union (EU) residents' (Data Subjects) rights concerning their personal data. Meteor Development Group Inc. (“MDG” also dba Apollo) stands ready to assist our customers to become or remain compliant with GDPR after this crucial transition.

What is GDPR?

GDPR standardizes EU regulations and expands the rights of Data Subjects pertaining to personal data while expanding the definition of what constitutes personal data. GDPR provides Data Subjects with increased rights to control and delete their personal data, and it broadly prohibits the processing of special categories of personal data.

How has Apollo prepared for GDPR?

We have been complying with GDPR since before it became enforceable on May 25, 2018. We are enhancing our products, processes, and procedures to meet our obligations as a data processor (Processor).

How will GDPR affect the way companies use Apollo's products or services?

Our products and services are not intended to be used for processing personal data. Our products and services are focused on software, systems, and applications - not individuals. If a customer wishes to set up a custom API, custom attribute, or custom event to track such data, it may do so. Our processing is data agnostic and automated, so all data is processed in the same way in accordance with a customer's configuration. If, however, a customer believes that it has included personal data in the information processed by Apollo, we will assist the customer in meeting its obligations in accordance with the requirements of GDPR and the terms of our Data Processing Agreement.

How can Apollo assist customers in meeting their obligations under GDPR?

As a Processor, we will assist customers in fulfilling their obligations as data controllers (Controllers) by:

  • supporting customers in complying with requests from Data Subjects
  • aggregating applicable personal data for customers replying to complaints from Data Subjects
  • replying to investigations and inquiries from supervisory authorities concerning processing activities on behalf of a customer
  • conducting Data Protection Impact Assessments

How can Apollo help address requests from Data Subjects?

Apollo has implemented a process to intake, review, and fulfill customer requests arising from Data Subject Access Requests (DSAR) they receive. As a result of a DSAR, customers might request that Apollo securely delete or return the Data Subject's personal data. Due to their sensitivity, such requests will be handled by Apollo on a case-by-case basis.

Where can I learn more about Apollo's security and privacy policies?

The legal terms and policies that apply to Apollo's corporate websites and customer products or services are available at https://www.apollographql.com/Apollo-Website-Terms-of-Service.pdf and https://www.apollographql.com/Apollo-Terms-of-Service.pdf.

Where can I get more help?

If you have any additional questions or encounter any issues, please reach out to support.

Organizations with an Enterprise plan can request a Data Processing Addendum (DPA) from support.

Requesting deletion of data

To request the deletion of specific data from your Apollo organization, please email [email protected] with the subject Data deletion request.

In your email, please include the following:

  • A description of the data that needs to be deleted
  • An approximate timestamp of when that data was reported to Apollo
  • The ID of the graph that the data is associated with

Currently, data deletion is performed across all variants of an affected graph. Per-variant deletion is not available.

You can also request that members of your organization be removed from marketing outreach. To do so, provide the email addresses of those members in your email.

Policies and agreements

To learn about other ways that we protect your data, please read over our Terms of Service and Privacy Policy.


File: src/content/graphos/basics/index.mdx


title: Introduction to Apollo GraphOS subtitle: The GraphQL developer platform

Apollo GraphOS is the platform for building, managing, and scaling a supergraph: a network of your microservices and their data sources—all composed into a unified GraphQL API.

mermaid
flowchart LR;
  clients("GraphQL<br/>Clients");
  subgraph "<b>Apollo GraphOS</b>";
  registry(["Schema<br/>Registry"]);
  router(["Graph<br/>Router"]);
  studio(["Studio UI"]);
  end;
  subgraph "Your infrastructure";
  products["GraphQL API<br/>A"];
  reviews["GraphQL API<br/>B"];
  router -->|Sub-query| products & reviews
  dbA[( )];
  dbB[( )];
  products --- dbA;
  reviews --- dbB;
  end;
  clients -.->|Query| router;
  class clients secondary;
text
Create your first supergraph!


What's a supergraph?

What's in GraphOS?

The GraphOS platform provides an ever-growing collection of tools and services to help you build your supergraph and scale it safely.

Core features

These features (along with many others) are available to organizations on Apollo Serverless and Dedicated plans:

  • Cloud routing
    • GraphOS automatically provisions and hosts a router for each of your supergraphs. Clients query your router instead of individual subgraphs, enabling the router to automatically collect operation metrics that you can then visualize in GraphOS Studio.
  • The schema registry
    • GraphOS tracks the GraphQL schemas for all your individual subgraphs, and it also handles composing those subgraph schemas into one supergraph schema for your router.
  • Safe schema delivery
    • The schema checks feature of GraphOS enables you to verify whether proposed changes to a subgraph will cause an issue with other subgraphs, or with any of your existing clients.
    • Whenever you update a subgraph schema, GraphOS composes a new supergraph schema for your router. If composition succeeds, your router automatically begins using its new schema.
    • You can view the results of each launch that takes place whenever you update a subgraph schema, helping you resolve any issues that might occur.
  • An interface for every use case
    • GraphOS Studio is the primary web interface for GraphOS. Among other capabilities, you use Studio to create your organization and its supergraphs, view schemas and metrics, and test out operations in the Explorer.
    • The Rover CLI is the primary command-line interface for GraphOS. Among other capabilities, you use Rover to publish subgraph schemas to the registry, run schema checks from CI, and test out your supergraph within your development environment.
    • If you want to automate your own workflows outside of Studio or Rover, you can use the official GraphOS Platform API to do so. We'll expose more GraphOS capabilities through the Platform API over time.

Enterprise features

Test out these features for free with an Enterprise trial.

Additional GraphOS features are available to organizations on an Enterprise plan:

  • Connect your self-hosted router to GraphOS
    • The Apollo Router Core is available as a free and source-available runtime for Apollo Federation. Connecting your self-hosted router to GraphOS requires an Enterprise plan. Once you connect the Apollo Router Core to GraphOS, it is called GraphOS Router.
    • Deploy GraphOS Routers inside your own infrastructure, enabling you to maximize performance and fully customize their behavior. Self-hosted routers use the same powerful technology that cloud routing uses under the hood.
    • Enable advanced features for your router fleet, such as operation limits and Redis-backed distributed caching.
  • Supergraph filtering with contracts
    • Deploy multiple instances of your router that each use a different filtered subset of your supergraph's schema. Different clients can then communicate with different routers, limiting them to whichever parts of your supergraph they should have access to.
  • Enhanced user management
    • Assign fine-grained user roles to organization members, and optionally override those roles on a graph-by-graph basis.
    • Set up single sign-on (SSO) with your identity provider.
    • Export audit logs of all material events that occurred within your organization over a time period.
  • Extended data retention
    • Your supergraph's historical operation metrics are available for visualization in Studio longer than with other plans. See the pricing page's section on data retention for details.

An Enterprise plan also provides access to our Graph Champions community and a dedicated support channel for your team to connect with Apollo supergraph experts. We'll work with you to customize a query volume limit and support package that's right for you.

If you're interested in Enterprise features, please get in touch with us! You can also test out these features with a free Enterprise trial.


Ready to create your first supergraph?

Get started with GraphOS!


File: src/content/graphos/basics/platform-api.mdx


title: The GraphOS Platform API subtitle: Automate GraphOS tasks in your own code

The GraphOS Platform API enables you to perform GraphOS actions from your own custom application. Currently, these actions include:

  • Fetching details about your organization's graphs
  • Publishing schemas to new or existing variants
  • Running schema checks and obtaining their results
  • Creating and editing schema proposals, including adding reviewers
  • Removing variants from a graph
  • Removing subgraphs from a supergraph
  • Managing API keys

We'll continue to expand the Platform API with additional GraphOS functionality over time.

API docs

The Platform API is itself represented as a public graph in GraphOS! Documentation for the API (which includes a README and collections of example operations) is available in GraphOS Studio.

text
Open Platform API docs

File: src/content/graphos/basics/routing.mdx


title: Routing for Supergraphs subtitle: Learn about self-hosted and cloud routing options

With supergraph architecture (also known as Apollo Federation), each component service is known as a subgraph. A router acts as an entry point to your subgraphs and provides a unified interface for clients to interact with. Clients send operations to your router's public endpoint instead of directly to your APIs.

mermaid
flowchart LR;
  clients(Clients);
  router(["Router"]);
  subgraphA[Subgraph A];
  subgraphB[Subgraph B];
  router --- subgraphA & subgraphB;
  clients -.- router;
  class clients secondary;

The router intelligently executes each incoming client operation across the appropriate combination of subgraphs. It then merges subgraph responses into a single response for the client. You can configure your router's error handling, CORS settings, other security features, and more. Your configuration options depend on your router type.

Router types

GraphOS comes with a fully integrated router called the GraphOS Router.
You can choose for Apollo to provision and manage a cloud-hosted GraphOS Router for you:

mermaid
flowchart LR;
  clients(Clients);
  subgraph "GraphOS Cloud"
    router(["GraphOS Router"]);
  end;
  subgraph YourInfra["Your infrastructure"];
    subgraphA[Subgraph A];
    subgraphB[Subgraph B];
  end;
  clients -.- router;
  router --- subgraphA & subgraphB;
  classDef padding padding-left:1em, padding-right:1em
  YourInfra:::padding
  class clients secondary;

Or you can choose to self-host your GraphOS Router:

mermaid
flowchart LR;
  clients(Clients);
  subgraph "Your infrastructure";
  router(["GraphOS Router"]);
  serviceB[Subgraph A];
  serviceC[Subgraph B];
  router --- serviceB & serviceC;
  end;
  clients -.- router;
  class clients secondary;

Both cloud and self-hosted GraphOS Routers are based on the Apollo Router Core—a high-performance routing runtime packaged as a standalone binary.

Apollo also offers the @apollo/gateway library, but we recommend GraphOS Routers over @apollo/gateway because they provide significant performance and security improvements. For more information about the differences and how to migrate, see the migration guide.

Router comparison

GraphOS offers the following router options, in increasing order of configurability:

Router type Description Configurability Plan availability
Shared cloud router Apollo provisions and manages routers on shared infrastructure. Basic configurability, including HTTP header rules, CORS settings, and
text
subgraph error inclusion | [Serverless](https://apollographql.com/pricing) |

| Dedicated cloud router | Apollo provisions and manages routers on dedicated infrastructure that
you control and scale. | Highly configurable, including all options for shared cloud routers and
additional configurations | Dedicated |
| Self-hosted router | You host and manage the router on your own infrastructure. | Highly configurable and customizable, including all options for Cloud
Dedicated routers and additional{' '}
customization options | The Apollo Core Router is available as a free and source-available
runtime. Connecting a self-hosted router to GraphOS requires an{' '}
Enterprise plan. |

GraphOS Router features

Although all GraphOS Routers (both cloud- and self-hosted) are based on the source-available Apollo Router Core binary, they offer an expanded feature set that isn't available when running the Apollo Router Core without connecting it to GraphOS.

Cloud-hosted routers automatically have access to GraphOS Router features, while self-hosted routers must be authenticated with a GraphOS Enterprise license to gain access to these features. Refer to the pricing page to compare GraphOS Router features across plan types.

Setup and configuration

For setup and configuration instructions, refer to the respective router documentation:


File: src/content/graphos/basics/sub-processors.mdx


title: Sub-Processors

Apollo Graph, Inc. ("Apollo") may use third-party data processors ("Sub-processors") to process Customer Personal Data as defined in the Apollo Customer Data Processing Addendum, or other personal data which you as customer are permitted to submit to Apollo for processing per our mutual written agreement ("Customer Personal Data"). Capitalized terms not defined on this page have the meanings given to them in the written agreement between you and Apollo (the "Agreement").

By subscribing to receive updates about this page, you will be notified by email about changes to Apollo's Sub-processors that may be involved in processing your Customer Personal Data.

Company Country Purpose/Use
Google Cloud United States Hosting Provider and Analytics Tool
PingOne United States User Management
GitHub United States User Management
Intercom United States Communication Provider
Slack United States Communication Provider
ZoomInfo United States Customer Management
LinkedIn (Sales Navigator) United States Customer Management
Salesforce United States Customer Management
Zendesk United States Customer Management
Unthread United States Customer Management
Marketo United States Marketing Management
Outreach United States Marketing Management
Hull United States Marketing Analytics
6Sense United States Marketing Analytics
Tableau United States Marketing Analytics
Recurly United States Billing Management

How to subscribe to updates

Subscribing to Sub-processor updates is temporarily turned off as we migrate our communication list. This article remains the canonical location for Apollo Sub-processor details.

View this article's edit history.

Current Apollo customers must subscribe to receive email notification of updates to Sub-processors and by submitting (1) the email address for such notifications and (2) the full name of the legal entity that has signed the Agreement with Apollo. By submitting this information, you represent that you are an Apollo customer and have all necessary rights to provide this information to Apollo.

How to object to a new Sub-processor

If you are a current Apollo customer, with a fully executed data processing agreement ("DPA") in place with Apollo, you may notify Apollo of an objection to its use of a new Sub-processor used to process Customer Personal Data by sending such objection to [email protected] within fourteen days after Apollo's notice of such new Sub-processor, or such other period of time as set forth in your DPA. Objections will be handled as described in the DPA.


File: src/content/graphos/basics/graphs/creating-a-subgraph.mdx


title: Creating a New Subgraph subtitle: Add a subgraph to your supergraph using a template or existing API

This article helps you get started building a new subgraph that you can then add to your GraphOS supergraph.

Starting from a template

The fastest way to create a new subgraph is to start with one of the templates provided by the Rover CLI. The rover template command generates the skeleton of a new subgraph for you, so you can immediately begin defining your schema and implementing your resolvers.

If your installed version of Rover doesn't include the template command (or if you don't have Rover installed at all), install the latest version.

You start by running rover template use, providing it the ID of your chosen template. For example, the following command creates a new directory called my-subgraph that contains the boilerplate code for a subgraph written in TypeScript using the Apollo Server library:

bash showlinenumbers=false
rover template use "my-subgraph" --template="subgraph-typescript-apollo-server"

To see the full list of available templates, see the Rover template docs

After generating the boilerplate code, you can start filling in your business logic. The generated code includes example resolvers for Query and Mutation, along with some entity types to use as your starting point. All templates also come with example GitHub Actions workflows to help with publishing your schema in CI/CD.

When you're ready to add your new subgraph to your supergraph, see below.

Starting with an existing API

If you have an existing GraphQL API that you want to use as a subgraph, confirm whether it uses a subgraph-compatible library.

  • If it does, consult the library's documentation to determine how to enable its support for Apollo Federation.
  • If it doesn't, open an issue to let us know and we'll work with the library's maintainers to add support.

Adding to your supergraph

When you're ready to add a new subgraph to your existing GraphOS supergraph, do the following:

  1. Enable federation support in your subgraph library.
    • If you built from a template, federation support is already enabled. Otherwise, consult the documentation for your chosen library.
  2. Check your schema against your existing supergraph and handle any conflicts.
  3. Set up your CI/CD pipeline to perform checks and also publish your subgraph schema.

After you publish your subgraph's schema for the first time, GraphOS recognizes it as part of your supergraph, and you can start querying for data from all your subgraphs!

Make sure you secure your subgraph so that only GraphOS can query it.


File: src/content/graphos/basics/graphs/federated-graphs.mdx


title: Supergraph-Specific Features subtitle: Learn about variants, managing subgraphs, and viewing compositions errors

GraphOS Studio provides tools to help multiple teams collaborate on a supergraph and its subgraphs.

Supergraph variants

Each variant of a Studio supergraph has its own subgraph schemas, supergraph schema, change history, and metrics.

Different variants of a supergraph can even have completely different sets of subgraphs:

mermaid
graph BT;
  subgraph "Staging"
  router2(["Router"]);
  users2[Users];
  products2[Products];
  reviews2[Reviews];
  router2 --- users2 & products2 & reviews2;
  end

  subgraph "Production"
  router(["Router"]);
  users[Users];
  products[Products];
  router --- users & products;
  end

This helps you test out adding new subgraphs (or removing existing ones) in non-production environments.

When you publish a subgraph's schema, you can specify which variant of the supergraph you're publishing that schema to.

Adding a variant

You can add a new variant to your existing GraphOS supergraph in the following ways:

Adding a variant in GraphOS Studio

This method of adding a variant is available only to cloud supergraphs. For other graph types, see Adding a variant via the Rover CLI

  1. Go to your supergraph's Settings page in Studio and navigate to This Graph > Variants.

  2. Click Add a variant.

  3. In the dialog that appears, provide a Variant Name and click Continue.

  4. Provide your first subgraph's Routing URL (this is the URL that your new variant's router will use to communicate with the subgraph), along with a Subgraph Name.

    • Creating a new supergraph variant always requires also creating the first subgraph for that variant.
  5. If Studio can't fetch your subgraph's schema automatically from the routing URL, click Advanced options to provide the schema another way (such as by pasting the schema directly or introspecting a locally running server).

  6. Click Add a new variant. When the action completes, your new variant is listed on your organization's homepage in Studio.

Adding a variant via the Rover CLI

To add a new variant to your supergraph with Rover, you publish its first subgraph's schema! To do this, you use the exact same Rover command as updating an existing subgraph. The only difference is that you provide the name of the new variant to the command.

Learn about publishing subgraph schemas.

Managing subgraphs

After you create a cloud supergraph (or a new variant of one), you can view a list of its associated subgraphs from the variant's Subgraphs page:

The list includes each subgraph's name and routing URL, along with type and field counts for each subgraph's schema.

Adding a new subgraph

You can add your new subgraph to your GraphOS supergraph in the following ways:

Adding a subgraph in GraphOS Studio

This method of adding a subgraph is available only to cloud supergraphs. For other graph types, see Adding a subgraph via the Rover CLI

  1. Go to your variant's Subgraphs page in Studio.

  2. Click Add a subgraph.

  3. In the dialog that appears, provide your subgraph's Routing URL (this is the URL that your supergraph's router will use to communicate with the subgraph), along with a Subgraph Name.

  4. If Studio can't fetch your subgraph's schema automatically from the routing URL, click Advanced options to provide the schema another way (such as by pasting the schema directly or introspecting a locally running server).

  5. Click Add Subgraph. When the action completes, your new subgraph is listed on the Subgraphs page.

Adding a subgraph via the Rover CLI

To add a subgraph to your supergraph with Rover, you publish the subgraph's schema! To do this, you use the exact same Rover command as updating an existing subgraph. The only difference is that you provide the name of the new subgraph to the command.

Learn about publishing subgraph schemas.

Modifying a subgraph

From your variant's Subgraphs page, you can modify an existing subgraph's routing URL:

  1. Open the ••• menu for the subgraph you want to modify:

  2. Click Edit routing URL.

  3. In the dialog that appears, provide a new URL and click Update.

    • Your router automatically begins using the new URL to communicate with your subgraph.

If you need to make any other modifications to an existing subgraph, use the Rover CLI. Learn about rover subgraph commands.

Deleting a subgraph

Deleting a subgraph is dangerous! Read this section fully before deleting a subgraph.

You can delete an existing subgraph from a variant of your cloud supergraph. If you do:

  1. The variant automatically attempts to compose an updated supergraph schema using the schemas from all remaining subgraphs.

    • Studio displays the result of this attempt, and you can cancel the deletion if there are errors.
  2. If composition succeeds, the variant's router automatically begins using the updated supergraph schema. This means clients can no longer query the router for fields that are defined only in the deleted subgraph.

    If composition fails, the router continues using its existing supergraph schema. This means clients can continue querying the router for fields from the deleted subgraph, until the remaining subgraph schemas are updated to compose successfully.

⚠️ Important considerations

  • Deleting a subgraph can break existing clients! This action is equivalent to removing all the subgraph's types and fields from your supergraph (unless they're also defined in another subgraph). If a client sends an operation that includes any of those types and fields, the router will reject that operation.

    • To help you remove schema definitions safely, learn about schema checks.
  • Deleting a subgraph in Studio has no effect on your actual running subgraph instance. It only removes your router's knowledge of that instance and its corresponding schema fields.

Steps to delete within Studio

  1. Go to the Subgraphs page for the subgraph's corresponding variant.

  2. Click the ••• button on the right of the subgraph you want to delete:

  3. Click Delete subgraph. Studio attempts to compose a new supergraph schema that doesn't include the subgraph you want to delete.

  4. A confirmation dialog appears that displays any composition errors that occurred. If you're sure you want to delete the subgraph, enter its name and click Delete subgraph.

Viewing a field's originating subgraph

The Schema > Reference page in Studio displays a table of your supergraph's types and fields. This table includes a Subgraph column, which lists the subgraphs that define each type and field:

Clicking the subgraph link for a type or field takes you to the line where it's defined in the corresponding subgraph schema:

If you're using the @contact directive to specify owner contact information for your subgraphs, hovering over a subgraph name displays its contact information, enabling you to follow up with the appropriate team:

Viewing subgraph SDL

The Schema > SDL page in Studio displays the raw SDL for each schema type associated with your supergraph—an API schema, a supergraph schema, and subgraph schemas.

From this page, you can:

  • View metadata about the composed supergraph, along with metadata about each subgraph (such its endpoint URL and most recent schema registration date)
  • Identify which subgraphs define any type or field in your API and share a link with team members
  • Search for types and fields
  • Download a copy of your subgraph's SDL for local development
  • Filter out comments and deprecated fields for improved scanning

Organization members with the Consumer role can only view the API schema. Observers, Documenters, Contributors, Graph Admins, and Org Admins can view all schema types.

Contact info for subgraphs

You can use the @contact directive to add your team's contact info to a subgraph schema. This info is displayed in Studio, which helps other teams know who to contact for assistance with the subgraph:

The contact info includes a name (of a team or individual), along with an optional description and custom URL.

Adding the `@contact` directive to your subgraph

To use the @contact directive in your subgraph schema, you first need to define the directive in your schema. Add the following definition to each of your subgraph schemas:

graphql title="schema.graphql"
"Annotate a schema with contact information for the subgraph owner"
directive @contact(
  "Contact title of the subgraph owner"
  name: String!
  "URL where the subgraph's owner can be reached"
  url: String
  "Other relevant notes can be included here; supports markdown links"
  description: String
) on SCHEMA

You can now apply the @contact directive to each subgraph schema's special schema object. If your schema doesn't already define this object, you can add it like so:

graphql title="schema.graphql"
extend schema
  @contact(
    name: "Acephei Server Team"
    url: "https://myteam.slack.com/archives/teams-chat-room-url"
    description: "send urgent issues to [#oncall](https://yourteam.slack.com/archives/oncall)."
  )

Supported `@contact` fields

Name /Type Description
##### name

String! | Required. The name of the person, people, or team responsible for the subgraph. |
| ##### url

String | The URL where the subgraph's owner can be reached. This might be the URL of a chat room or forum, or it could be an email address. |
| ##### description

String | Provides any additional helpful details about working with this subgraph or contacting its owner.

This field supports Markdown-formatted links. |

Known `@contact` limitations

  • To provide the @contact directive to Apollo, you must publish your subgraph schemas by providing a local .graphql file as the --schema option of rover subgraph publish.
    • If you provide an introspection result to the command instead, the @contact directive is not included in that result.

Viewing contact info

After you publish a subgraph schema that includes the @contact directive, the contact information is included in the metadata shown in Studio's Schema > SDL tab:

In the Schema > Reference tab, you'll also see a contact card when you hover over the subgraph link of a type or field:

Schema tagging

In your subgraph schemas, you can use the @tag directive to tag a type or field with an arbitrary string value:

graphql {4} title="products.graphql"
type Product {
  id: ID!
  name: String!
  codename: String! @tag(name: "internal")
}

By default, these tags are removed from the API schema that's generated as part of composition. This means that tag information isn't visible to clients querying your supergraph.

If tag information should be visible to clients (for example, to help document your API), you can enable this for a variant in Studio with the following steps:

  1. Go to the Settings page for your variant in GraphOS Studio.
  2. On the General tab, click Edit Configuration. The Update Build Configuration dialog appears.
  3. If you have a Federation 1 supergraph, enable the toggle for the @tag directive under Directives (this step isn't necessary for Federation 2 supergraphs).
  4. Under Build Settings, enable the toggle labeled Show all uses of @tag directives to consumers in Schema Reference and Explorer.
  5. Click Save.

After you make your @tag directives visible, you can view them inline with both the Schema and Explorer tabs in Studio.

In the Schema > Reference tab, tags are shown inline with each type and field:

Supergraph support in the Explorer

The GraphOS Studio Explorer provides enhanced support for working with supergraphs:

  • You can preview how your supergraph's router resolves data for an operation by inspecting the operation's query plan in the Response pane.
  • While you're building operations in the Explorer, you can see which subgraph each field of your operation originates in by enabling subgraph hints from the Explorer's Settings tab.

Viewing composition errors

If a supergraph's most recent set of subgraph schemas failed to compose, a BUILD FAILED label is shown at the top of the supergraph's page in Studio. You can click this label to view the errors that must be resolved before composition can succeed. Refer to the composition error reference for more information.


File: src/content/graphos/basics/graphs/index.mdx


title: Understanding Graphs subtitle: Learn about graph types, variants, and how to publish schemas

GraphOS is a platform for building and managing graphs. Each graph corresponds to a GraphQL service in your organization.

A GraphQL service usually runs in more than one environment—for example, staging or production—so every graph in GraphOS has one or more variants that each correspond to one environment:

mermaid
graph LR;
  subgraph "A graph in GraphOS";
    direction TB
    staging(Staging<br/>variant);
    production(Production<br/>variant);
  end;

Each variant of a graph keeps track of its own separate GraphQL schemas and operation metrics.

Graph types

Every graph in GraphOS is one of these graph types:

Graph type Description
Cloud supergraph A supergraph consisting of:
  • A GraphOS Router
  • One or more subgraphs hosted in your infrastructure

Recommended for all organizations getting started with GraphOS. |
| Self-hosted supergraph

(Enterprise only) | A supergraph consisting of:

  • A GraphOS Router hosted in your infrastructure
  • One or more subgraphs hosted in your infrastructure

Recommended for enterprise organizations that require full customization of their router, usually for advanced performance or data compliance reasons. |
| Monograph

(Enterprise only) | A single GraphQL service hosted in your infrastructure with no router.

⚠️ Not recommended. |

Cloud supergraphs

Cloud supergraphs require an Apollo organization on the Serverless (free or paid) or Dedicated plan.

Cloud supergraphs are recommended for every organization that's getting started with GraphOS. For every variant of a cloud supergraph, GraphOS provisions and manages a router that acts as the variant's public endpoint. Application clients communicate with this endpoint instead of communicating directly with your GraphQL server(s):

mermaid
flowchart LR;
  clients(Clients);
  subgraph "GraphOS Cloud";
  router(["GraphOS Router"]);
  end;
  subgraph "Your infrastructure";
  api["Your GraphQL<br/>server"];
  router --- api
  end;
  clients -.- router;
  class clients secondary;

The router automatically reports certain operation metrics to GraphOS, so you don't need to configure this reporting in your GraphQL servers.

Learn more about cloud routing.

Cloud supergraphs use an architecture called Apollo Federation. With federation, you can distribute your supergraph's capabilities across multiple GraphQL services, which are known as subgraphs. The router executes client operations across multiple subgraphs as needed:

mermaid
flowchart LR;
  clients(Clients);
  subgraph "GraphOS Cloud";
  router(["GraphOS Router"]);
  end;
  subgraph "Your infrastructure";
  products[Products subgraph];
  reviews[Reviews subgraph]
  router --- products & reviews
  end;
  clients -.- router;
  class clients secondary;

Even if your API currently uses only one GraphQL server, a cloud supergraph helps you add more subgraphs later as your organization grows.

text
Get started with a cloud supergraph

Self-hosted supergraphs

Self-hosted supergraphs are an Enterprise feature for organizations with advanced performance or compliance requirements. If your organization doesn't currently have an Enterprise plan, you can test out this functionality by signing up for a free Enterprise trial.

With a self-hosted supergraph, GraphOS does not provision a router for your supergraph. Instead, you host your supergraph's router in your own infrastructure:

mermaid
flowchart LR;
  clients(Clients);
  subgraph "Your infrastructure"
  router(["GraphOS Router"]);
  serviceA[Products subgraph];
  serviceB[Reviews subgraph];
  router --- serviceA & serviceB;
  end;
  clients -.- router;
  class clients secondary;

Self-hosted supergraphs provide full control over your router, but they also require handling its deployment and management. Before you adopt this graph type, make sure you have the necessary team structure to properly manage an additional service in your infrastructure.

text
Get started with a self-hosted supergraph

Monographs

Monographs require an Apollo organization on the Enterprise plan.

A monograph is a graph that consists of a single GraphQL server with no router:

mermaid
flowchart LR;
  clients(Clients);
  subgraph "Your infrastructure"
  server[GraphQL server];
  end;
  clients -.- server;
  class clients secondary;

Apollo strongly recommends against monographs. A monograph introduces technical and logistical scaling issues as more teams contribute to your graph and its schema.

Additionally, the router provides essential GraphOS functionality beyond support for multiple subgraphs. It also enables powerful features like @defer support and straightforward metrics reporting.

Creating graphs

You can create a cloud supergraph or a non-cloud supergraph (self-hosted or monograph).

<Tabs labels={['Cloud','Non-cloud']}>

To create a cloud supergraph, see the GraphOS quickstart.

To create a non-cloud graph, follow these steps:

  1. Go to your organization's Graphs tab in GraphOS Studio.

  2. Click Create New Graph in the top right.

  3. In the dialog that appears, specify an Organization and Graph title for your graph.

  4. Specify your Graph Architecture:

    • To create a self-hosted supergraph, leave this as Supergraph (default).
    • To create a monograph, switch this to Monolith.
  5. Click Next. A dialog like the following appears (the details differ depending on which Graph Architecture you're using):

  6. If you're creating a self-hosted supergraph, select the version of Apollo Federation you're using from the Supergraph Pipeline Track dropdown.

Your graph has been created.

Next, you need to publish your graph's schema(s) to Apollo using the Rover CLI. For details, see Publishing schemas to GraphOS.

Variants

To distinguish between instances of the same graph running in different environments (such as staging and production), you define multiple variants of your graph. Each variant has its own schemas, along with its own change history and metrics.

Each of your graph's variants is shown in GraphOS Studio:

Creating a variant

See this section.

Publishing schemas

See Publishing schemas to GraphOS.


File: src/content/graphos/basics/graphs/local-development.mdx


title: Local Subgraph Development subtitle: Use the Rover CLI to run a local supergraph

While you're working on changes to one of your subgraphs, you can run a version of your entire supergraph locally in your development environment. To do this, you use the rover dev command.

Install the Rover CLI.

The rover dev command monitors each of your subgraph schemas (either via server introspection or by watching a .graphql file). Whenever it detects a change, it automatically recomposes your router's supergraph schema and raises any errors that might occur. This enables you iterate quickly on schema changes.

Starting your router

You run rover dev once for each subgraph in your supergraph. The first time you run it, Rover spins up a router on your local machine.

Try running rover dev with an example subgraph like so:

bash showlinenumbers=false
rover dev --url https://flyby-locations-sub.herokuapp.com/ --name locations

You'll see output like the following:

text
WARN: could not detect a schema in the current working directory. to watch a schema, pass the `--schema <PATH>` argument
👂 polling https://flyby-locations-sub.herokuapp.com/ every 1 second
⚠️  Do not run this command in production! ⚠️  It is intended for local development.
🛫 starting a session with the 'locations' subgraph
🎶 composing supergraph with Federation v2.1.2
🚀 your supergraph is running! head to http://localhost:3000 to query your supergraph

You can now open http://localhost:3000 in your browser and run test queries against your local router using the Explorer!

You can replace the example subgraph URL and name in the above command with the details for your own subgraph. You can provide a remote URL or a localhost URL.

Adding a subgraph

To add a subgraph to your local supergraph, run rover dev again in a separate terminal window.

You can add a subgraph to this article's example supergraph with the following command:

bash showlinenumbers=false
rover dev --url https://flyby-reviews-sub.herokuapp.com/ --name reviews

This command's output is similar to the output for the initial execution, but it includes a line like the following:

text
🐤 adding the 'reviews' subgraph to the session

This indicates that rover dev has identified your existing supergraph session and is adding this subgraph to it.

Now if you run test queries in the Explorer, you'll see that they can include fields from both the locations and reviews subgraphs!

Ending a `rover dev` session

To shut down your local supergraph, use CTRL+C to stop the first rover dev process you started. This automatically terminates all secondary rover dev processes that are part of the same session.

If you stop a secondary rover dev process, your session remains active, and the router's schema is automatically updated to reflect the removed subgraph.

Command options

For more details on rover dev options, see the Rover documentation.


File: src/content/graphos/basics/graphs/management.mdx


title: Graph Management in GraphOS subtitle: Manage access permissions and transfer and delete graphs

Creating graphs

Managing access permissions

Public variants

You can enable public access for individual variants of your graph. If you do, anyone with that variant's public link can view the following pages for that variant in Studio:

  • Home
    • This shows the variant's README.
  • Schema
  • Explorer

This enables consumers of your graph to learn about your graph's schema and any special usage information (such as authentication details) that you've documented in the public variant's README. They can also run properly authenticated operations against your graph with the Explorer.

People outside your organization can't view any other pages for a public variant (Fields, Operations, etc.), and they can never view any pages for private variants. New variants always start as private.

Making a variant public

Only organization members with the Org Admin or Graph Admin role can toggle a variant's public visibility.

  1. Go to your variant's Settings page and open the This Variant tab.
  2. Under Danger Zone, find the Public card and click Change.
  3. Toggle your selection and click Save.

You can toggle the switch back to Off to make the variant private again.

After you make a variant public, you can click the variant's PUBLIC label at the top of GraphOS Studio to get its public link:

Protected variants (Enterprise only)

If you have a GraphOS Enterprise plan, you can designate particular variants of a graph as protected variants. A protected variant limits the capabilities of users with the Contributor role to make certain changes to the variant:

  • Contributors cannot push schema updates to a protected variant.
  • Contributors cannot manage Explorer-related settings for a protected variant, such as setting the variant's endpoint URL.
  • Graph API Keys with the Contributor role cannot report usage metrics for a protected variant.

Graph Admins and Org Admins can configure whether a variant is protected from the This Variant tab of the variant's Settings page.

Internal graph visibility (Enterprise only)

For external graph visibility, see Public variants.

By default, graphs are visible to all members of your organization. If you have a GraphOS Enterprise plan, you can set a graph to instead be visible only to members you invite.

You can configure visibility and grant your organization's members explicit access to your graph from the Permissions tab of your graph's Settings page.

Org Admins can always see all graphs in your organization.

Dangerous actions

Transferring graph ownership

You can transfer a graph to a different GraphOS organization you belong to
by visiting the graph's Settings page in Studio and changing the graph owner.

Deleting a graph

Deleting a graph cannot be undone.

If you delete a cloud supergraph, all its GraphOS-hosted routers are deprovisioned.

You can delete a graph from Studio by visiting its Settings page and clicking
Delete Graph.


File: src/content/graphos/basics/graphs/securing-a-subgraph.mdx


title: Securing Subgraphs subtitle: Restrict access to your cloud supergraph using secrets

To keep your supergraph secure, it's important that your individual subgraphs are queried only by your router. That's because your subgraphs expose powerful fields that the router uses to execute operations across them. External clients should not have access to these fields.

This article describes steps for securing your subgraphs when using a cloud supergraph.

As with all changes, we recommend first performing these steps for a non-production variant of your supergraph.

Step 1. Generate a shared secret

To restrict subgraph communication to only your router, we recommend creating a separate shared secret for each of your subgraphs. Whenever your router queries a subgraph, it includes that subgraph's corresponding secret in an HTTP header.

You can generate a random secret using a variety of tools. For example, most password managers provide this functionality.

Here are some shell commands that generate a suitably random secret if you have the corresponding tool installed:

  • openssl rand -base64 256
  • python -c "import secrets; print(secrets.token_urlsafe(256))"
  • node -e "console.log(require('crypto').randomBytes(256).toString('base64'));"

Step 2. Add the secret to your router config

Your cloud supergraph's router needs to know the shared secret so it can include it in all requests to the corresponding subgraph. You add the secret in the Cloud Routing section of your graph variant's Settings page.

For details, see Managing secrets.

After you define the secret, you can inject its value into your router's configuration as an environment variable, as shown below. We recommend setting the value in a header named Router-Authorization (and again, create a separate secret for each subgraph):

yaml
headers:
  subgraphs:
    products:
      request:
        - insert:
            name: 'Router-Authorization'
            value: '${env.PRODUCTS_SUBGRAPH_SECRET}'
    users:
      request:
        - insert:
            name: 'Router-Authorization'
            value: '${env.USERS_SUBGRAPH_SECRET}'

Step 3. Configure the subgraph to require the secret

The exact steps you take to require the shared secret in your subgraph depend on:

  • The language and framework your subgraph uses
  • The service you use to host your subgraph

Most cloud providers include a mechanism for saving secrets that are then made available to your application as environment variables. Your subgraph should read the secret from an environment variable and reject any incoming requests that don't include that secret in the specified header.

All subgraph templates provided by the Rover CLI include this functionality out of the box. To use it, set the value of the ROUTER_SECRET environment variable.

If you have an existing subgraph that wasn't created from a template, you can check a similar template's source code for an example.

Step 4. Test the configuration

After adding the shared secret to both your router and subgraph, do the following to confirm that communication has been secured as intended:

  1. Verify that your router can still communicate with the subgraph by executing a test query against the router from the Explorer.
    • Make sure the query includes at least one field from the relevant subgraph!
  2. Verify that other clients can't communicate with the subgraph by executing a test query against the subgraph directly.
    • This query should fail with an authorization error.

File: src/content/graphos/basics/graphs/studio-features.mdx


title: Graph Exploration subtitle: Explore and visualize your graph's types, fields, and relationships

As your graph grows, understanding its structure can become more difficult.
Without understanding a schema's intricacies—particularly how subgraphs relate to one another—development can become blocked or take wrong turns.

GraphOS Studio features

GraphOS Studio provides several ways of understanding and exploring your organization's graphs, including:

  • An editable Overview page that describes the graph to newcomers
  • The Schema page, which includes three distinct views, including schema visualization
  • The Explorer, which helps you build new operations against your graph
  • The Changelog, which displays all published changes

These GraphOS Studio features are available for all graph types. For features specific to supergraphs, see Supergraph-specific Studio features. See Variant pages for the full list of Studio pages.

Viewing graph pages

After selecting an organization in GraphOS Studio, click a particular graph variant to view its pages.

Page permissions

With Serverless and Dedicated plans, all Studio organization members have access to all pages, including Settings for all graphs within the organization. Enterprise accounts can set member roles to configure fine-grained access for individual members of their organization.

The Overview page

When a user opens one of your graph's variants in GraphOS Studio, its Overview page appears. Like a typical homepage for a Git repository, this page displays a Markdown-based README that you can edit with any content you like.

Only organization members with the Org Admin, Graph Admin, Contributor, or Documenter role can edit a variant's README. If a variant is protected, Contributors can't edit its README.

Each variant has its own README. If you edit one variant's README, those edits aren't applied to other variants. Among other uses, this enables you to provide different information to external consumers in a public variant.

Supported Markdown

The README supports all basic Markdown syntax and most extended syntax, including tables, code blocks, and footnotes.

You can define a GraphQL code block with the following syntax:

text
```graphql
query MyQuery {
  users {
    id
    name
  }
}
```

This renders the code block with buttons to copy an operation or open it in the Explorer.

README shortcodes

The README supports a set of shortcodes. These shortcodes can populate the README with data specific to your variant, like the graph's name and the variant's graph ref:

md
# Overview of {{ graph.name }}

Graph ref: {{ graph.ref }}

For a list of all supported shortcodes, click Graph shortcodes in the bottom-left corner of the README editor.

The Schema page

A graph variant's Schema page has three distinct views:

  • The Reference tab lets you filter your schema's type and field definitions
  • The SDL tab displays your schema's raw SDL
  • The ** Visualization** tab provides a filterable, navigable, graphical representation of your schema

Schema reference

The Reference tab on the Schema page lists the different kinds of definitions in your schema, for example, objects, scalars, interfaces, etc.

Select a kind of definition to view a table of all corresponding types:

Each type definition in the table includes:

  • The type's name
    • You can click the name to view additional details for the type, such as fields for an object, or possible types for a union.
  • The type's description, if your schema includes one
  • Which subgraphs define the type, if you have a federated supergraph
    • Users with the Consumer role can't view subgraph details.

Filtering your schema

The top of the Schema page provides a Filter Schema box you can use to find types and fields that match a set of filters:

  • Click the arrow button to the left of the filter box to show/hide the filter selection dropdowns.
  • Click the button to the right of the filter box to copy a shareable URL of your currently active set of filters.
    • You can also copy your browser's address bar directly.

Any filters you set remain active as you move between definitions on the Schema page.

You can filter your schema definitions by type/field name, as shown above, along with any combination of the following:

Filter Description Example
##### subgraph Include results defined in any of the specified subgraphs.

Valid only for federated supergraphs. | subgraph:products,reviews |
| ##### tag | If your graph uses the @tag directive, include results that have a @tag with any of the specified names. If viewing a table of objects, also include objects with at least one field that has a specified @tag.

If your graph doesn't use the @tag directive, this filter isn't available. | tag:internal,experimental |
| ##### directive | Include results that have any of the specified directives applied. If viewing a table of objects, also include objects with at least one field that has a specified directive. | directive:deprecated,unused |
| ##### returnType | Include results with any of the specified return types. If viewing a table of objects, include objects with at least one field that has a specified return type.

This filter includes all fields that return a particular type, regardless of each field's nullability or whether it returns a list. For example, if you specify returnType:Int, the filter includes fields that return any of Int, Int!, or [Int]. | returnType:Int,String |
| ##### argument | Include results that take a GraphQL argument with any of the specified names. If viewing a table of objects, include objects with at least one field that takes a specified argument. | argument:offset,limit |

Filtering rules

  • If you list multiple possible values in a single filter, those values use OR logic.
    • For example, if you filter by subgraph:products,reviews the result includes definitions from each subgraph.
  • If you apply multiple types of filters, those filters use AND logic.
    • For example, if you filter by subgraph:products and returnType:Int, the result includes only definitions that fulfill both criteria.
  • Currently, it isn't possible to use AND logic for multiple filters of the same type.
    • For example, it isn't possible to filter by subgraph:products AND subgraph:reviews to include only definitions that are present in both subgraphs.

Schema definition language

The SDL tab displays the raw schema definition language (SDL) for each schema associated with your graph. For a monograph, this is simply the graph's API schema. Supergraphs also include a supergraph schema and subgraph schemas. See Viewing subgraph SDL for more information.

Regardless of the SDL type you're viewing, you can Copy the SDL or download it in Raw or JSON format from this tab.

Schema visualization

The Visualization tab provides a graphical representation of your schema's structure, including types, fields, and relationships.
It can help clarify your understanding of your schema's design, so you can more easily identify potential issues and improve your data model.

The Explorer

GraphOS Studio provides a powerful Explorer IDE that helps you visualize your graph and run queries against it. It's available from your graph's Explorer page in Studio. Refer to the Explorer docs to learn more.

Tracking schema changes

The Changelog page in Studio displays a timeline of changes made to your graph's schema.
Only schema changes that you publish to Studio are in this timeline, which is one of the most important reasons to include schema publishing in your continuous delivery pipeline.


File: src/content/graphos/basics/graphs/updating.mdx


Your supergraph consists of multiple components that are each versioned independently:

mermaid
flowchart LR;
  subgraph "GraphOS";
  router(["GraphOS Router"]);
  pipeline[["🛠<br/>Build<br/>pipeline"]];
  end;
  subgraph "Your infrastructure";
  products[Subgraph A];
  reviews[Subgraph B]
  router --- products & reviews
  end;
  • The GraphOS Router is based on a version of the Apollo Router Core.
  • The GraphOS build pipeline uses a particular version of Apollo Federation to compose your router's supergraph schema.
    • If you use the Rover CLI to compose your supergraph schema, this is true for Rover as well. In this case, you effectively maintain your own build pipeline.
  • Your subgraph schemas might each use special directives that were first introduced in a particular version of Apollo Federation.

These components each target support for a particular version of Apollo Federation, the architecture that underpins every supergraph. Because of this, it's important to make sure these various Federation versions remain compatible with each other as you make updates to individual components.

To avoid runtime or composition errors, your supergraph's components should always maintain the following relationship between their targeted Apollo Federation versions:

(Router fed. version) ≥ (Build Pipeline fed. version) ≥ (Subgraph fed. version)

To maintain this relationship, always update these supergraph components in order from left to right:

mermaid
graph LR;
  router(1. Router)
  router --> pipeline(2. Build Pipeline);
  pipeline --> subgrahs(3. Subgraph Schemas);

1. Update your router

The method you use to update your router depends on which type of supergraph you have:

For details on each router version's corresponding Apollo Federation version, see this article.

2. Update your build pipeline

Whenever you make an operational change to your graph (such as publishing changes to a subgraph schema), GraphOS initiates a build that composes your graph's new supergraph schema. From GraphOS Studio, you can configure which version of Apollo Federation the build pipeline uses to perform this composition.

GraphOS enables you to choose between minor versions of Federation (such as 2.1). Each option automatically uses the latest supported patch release of that minor version (such as 2.1.4).

Although patch release updates are automatic, you must manually move a graph's build pipeline to a different minor release.

  1. Go to your variant's Settings page, then find the General > Build Pipeline section.

  2. Click Upgrade.

  3. In the dialog that appears, select a Federation version from the dropdown and click Save.

GraphOS immediately initiates a new build using the selected Federation version. All future builds also use the selected version.
Successful build completion triggers a launch that delivers an updated schema to your router.

Composing with the Rover CLI

If you host your own GraphOS Router instance, you can use the Rover CLI to compose its supergraph schema via the rover supergraph compose command.

Performing composition with Rover is not recommended. Instead, perform composition via the GraphOS build pipeline to help ensure a consistent schema delivery process across all your graph's environments.

If you do perform composition with rover supergraph compose, the command uses the exact version of composition you specify via the federation_version key in the YAML configuration file you pass:

bash showlinenumbers=false
rover supergraph compose --config ./supergraph.yaml
yaml title="supergraph.yaml"
federation_version: =2.3.2 #highlight-line
subgraphs:
  # ...

This value must target a specific patch release (2.3.1, 2.3.2, etc.), and it must start with an equals sign (=).

If you don't provide a value for federation_version, Rover prints a warning and chooses a composition version according to this logic. This could potentially cause failures. Rover might use a newer composition version than what your router supports, resulting in a supergraph schema that causes the router to fail on startup.

Learn more about setting a Rover composition version.

3. Update subgraph schemas (as needed)

After both your router and your build pipeline support a particular minimum version of Apollo Federation, your subgraphs can use features that were first introduced in that version.

You don't need to update any subgraph schema that doesn't use newly introduced Apollo Federation features. Different subgraph schemas can target different Federation versions as needed. Ultimately, your build pipeline determines which version of composition is actually used to create the supergraph schema.

As an example, the @interfaceObject directive was first introduced in Federation 2.3. To start using this directive in a subgraph, do the following:

  1. Make sure your chosen subgraph library has added support for the @interfaceObject directive by consulting this table.

    • If your library doesn't yet support the directive, reach out to its maintainers about adding support.
  2. Upgrade to the latest version of your subgraph library to make sure you're using a version that supports @interfaceObject.

  3. Modify the following @link directive in your subgraph schema (or add it if it isn't present yet):

    graphql
    extend schema
      @link(
        url: "https://specs.apollo.dev/federation/v2.3"
        import: ["@key", "@shareable", "@interfaceObject"]
      )

    Notice that the url argument targets v2.3 of the Apollo Federation spec, and @interfaceObject is included in the import list.

  4. Apply the @interfaceObject directive to relevant locations in your subgraph schema.

Because you've already updated your router and build pipeline, the next time you deploy your subgraph and publish its schema to GraphOS, every component in your supergraph will be prepared to interact with a schema that includes the @interfaceObject directive you've added.

Why is this update order necessary?

GraphOS supergraphs use the Apollo Federation 2 architecture. Federation 2 is itself a versioned technology (2.2, 2.3, etc.), and each version introduces changes and additions to the set of supported subgraph directives.

  • Each version of the GraphOS Router is compiled against a particular version of Federation 2 (for details, see this table). Any given router version is backward compatible with previous versions of Federation. However, it isn't compatible with newer versions.

    Therefore, it's important to update your router first, before any other supergraph component begins using a later Federation 2 version. Otherwise, you might cause your router to break by providing it a supergraph schema that it doesn't support.

  • Your graph's Supergraph Pipeline Track setting in GraphOS Studio determines which version of Federation 2 is used to compose your supergraph schema. This composition process fails if one of your subgraph schemas uses a directive that was introduced in a Federation version later than your chosen pipeline track.

    • In the case of a failed build, GraphOS continues to provide your router with the supergraph schema from the most recent successful build.
  • Finally, subgraph schemas are where you actually apply new Federation 2 directives. You need to update your subgraph library to a version that recognizes all directives that you use in your schema.

    You perform this update last to make sure that every other component of your supergraph is prepared to interact with any newly introduced directives.


File: src/content/graphos/basics/operations/defer.mdx


title: Deferring Query Response Data subtitle: Using the @defer directive

With GraphOS, your supergraph's router can defer returning data for certain fields in your schema. This enables a querying client to receive non-deferred data more quickly, because the router can return it immediately instead of waiting for all response data to be ready:

mermaid
sequenceDiagram
  Client->>Router: Sends a query that<br/>defers some fields
  Note over Router: Resolves non-deferred<br/>fields
  Router->>Client: Returns data for<br/>non-deferred fields
  Note over Router: Resolves deferred<br/>fields
  Router->>Client: Returns data for<br/>deferred fields

Both cloud supergraphs and self-hosted supergraphs support deferring fields with the router. Additionally, this feature is compatible with all supported subgraph libraries, because the logic resides entirely within the router!

How do I defer fields in a query?

Deferring query fields requires a defer-compatible client library. These libraries support receiving query data incrementally via multipart HTTP responses.

Defer support is currently available in Apollo Client for Web and Kotlin (experimental).

If you're using a defer-compatible client, you apply the @defer directive to fragments in your queries to specify which fields you want to defer:

graphql
query GetTopProductsAndReviews {
  topProducts {
    id
    name
    # highlight-start
    # You always apply @defer to a fragment, not to individual fields
    ... @defer {
      reviews {
        score
      }
    }
    # highlight-end
  }
}

When your supergraph's router receives this query, it defers every field in these fragments that it's able to.

Which fields can my router defer?

Your supergraph's router can defer the following fields in your schema:

  • Root fields of the Query type (along with their subfields)
  • Fields of any entity type (along with their subfields)
    • Deferring entity fields is extremely powerful but requires some setup if you aren't using entities already. This is covered in more detail below.

See below for more information on each of these.

`Query` fields

Your router can defer any field of your schema's Query type, along with any subfields of those fields:

graphql
query GetUsersAndDeferProducts {
  users {
    id
  }
  # highlight-start
  ... @defer {
    products {
      id
    }
  }
  # highlight-end
}

With the query above, the router first returns a list of User IDs, then later completes the response with a list of Product IDs.

Entity fields

Your router supports deferring fields of the special object types in your supergraph called entities.

Entities are object types that often define their fields across multiple subgraphs (but they don't have to). You can identify an entity by its use of the @key directive. In the example subgraph schemas below, the Product type is an entity:

graphql title="products subgraph"
type Product @key(fields: "id") {
  id: ID!
  name: String!
  price: Int!
}

type Query {
  topProducts: [Product!]!
}
graphql title="reviews subgraph"
type Product @key(fields: "id") {
  id: ID!
  reviews: [Review!]!
}

type Review {
  score: Int!
}

Entities are query entry points into your subgraphs, and this is what enables your router to defer their fields: the router can send a followup query to a subgraph to fetch any entity fields that it doesn't fetch initially.

Here's an example query that defers entity fields using the subgraphs above:

graphql
query GetProductsAndDeferReviews {
  topProducts {
    id
    name
    # highlight-start
    ... @defer {
      reviews {
        score
      }
    }
    # highlight-end
  }
}

To handle this query, the router first resolves and returns a list of Product objects with their IDs and names. Later, the router completes the response by returning review scores for each of those products.

It doesn't matter which subgraph defines a particular entity field! Queries can defer entity fields that are defined across any number of different subgraphs.

Defining entities in your subgraphs

If your subgraphs don't yet include any entities, you need to define some before clients can start deferring their fields in queries.

To learn about creating entities, see this article.

Requirements for `@defer`

To use @defer successfully, your supergraph and its clients must meet the requirements listed below. These requirements are divided between general requirements (requirements for using @defer at all) and entity-specific requirements (additional requirements for using @defer with entity fields).

General requirements

Entity-specific requirements


File: src/content/graphos/basics/operations/persisted-queries.mdx


title: Safelisting with Persisted Queries subtitle: Secure your graph while minimizing request latency

GraphQL APIs are broadly open by design to provide flexibility and efficiency in client development. However, this openness also introduces the risk of potentially malicious requests and the subsequent need to secure your graph.

Differences from automatic persisted queries

The router also supports a related feature called automatic persisted queries (APQ). With APQ, clients can execute a GraphQL operation by sending the SHA256 hash of its operation string instead of the full string.

APQ has a few limitations compared to registered persisted queries.

Automatic persisted queries Registered persisted queries
Operation performance ✅ Clients can send identifiers instead of full operation strings, reducing request sizes and latency
text
dramatically. | 🌟 Registered persisted queries share the same performance enhancement mechanism as APQs. Additionally, they
    benefit from query plan [cache warm-ups](/router/configuration/in-memory-caching/#cache-warm-up),
    which are active by default from version
    [1.31.0](https://github.com/apollographql/router/releases/tag/v1.31.0) of the router. |

| Build- vs. runtime registration | Operations are registered at runtime. One of your router instances must receive any given operation string
from a client at least once to cache it. | Clients contribute to the PQL at build-time. Your router fetches its PQL from GraphOS on startup and polls
for updates, meaning clients can always execute operations using their PQL-specified ID. |
| Safelisting | ❌ APQ doesn't provide safelisting capabilities because the router dynamically populates its APQ cache over time
with any operations it receives. | ✅ Clients preregister their operations to GraphOS. Your router fetches its PQL on startup, enabling it
to reject operations not present in the PQL. |

If you only want to improve request latency and bandwidth usage, APQ addresses your use case. If you also want to secure your supergraph with operation safelisting, you should register operations in a PQL.

Security levels

The GraphOS Router supports the following security levels, in increasing order of restrictiveness:

Security Level Description
Allow operation IDs Clients can optionally execute an operation on your router by providing the operation's PQL-specified ID.
Audit mode Executing operations by providing a PQL-specified ID is still optional, but the router logs any unregistered
text
operations. |

| Safelisting | The router rejects any incoming operations that aren't in its PQL. Clients can use either PQL-specified IDs or
operation strings to execute operations. |
| Safelisting with IDs only | Clients can only execute operations by providing their PQL-specified IDs; the router rejects all
freeform GraphQL requests. |

You can find more details, including configuration instructions, in the implementation section.

These levels allow you to incrementally adopt persisted queries on a client-by-client basis. Specifically, the router should use audit mode until you're confident that all your clients' trusted operations have been registered in the PQL. Refer to the incremental adoption section for a step-by-step guide.

Implementation steps

Persisted queries provide benefits to different teams:

  • Safelisting helps platform teams secure the graph and optimize its performance.
  • Application developers can use registered operation IDs to write performant client code.

Implementation also requires collaboration among these parties. These are the main steps for implementing persisted queries for safelisting, along with the team that usually performs them:

Step Description Responsible party
1. PQL creation and linking Create and apply a PQL to graph variants. Platform team
2. Router configuration Update your router's YAML config file to enable
text
persisted queries at the appropriate [security level](#security-level). | Platform team |

| 3. Operation registration | Generate and publish a persisted queries manifest (PQM) to the PQL from your client's CI/CD pipeline. | App developers |
| 4. Client updates (Optional) | Update clients to use operation IDs rather than full operation strings.

text
*This step provides performance benefits but isn't necessary for safelisting.* | App developers |

Continue reading for each step's details, or skip to the incremental adoption section for the recommended incremental adoption strategy. (This section assumes you have a high-level understanding of each implementation step.)

1. PQL creation and linking

To use persisted queries, you first need a persisted query list (PQL) in GraphOS Studio.
Platform teams create an empty PQL in GraphOS Studio so that client teams can register operations to it.

Each PQL is associated or "linked" with a single graph in GraphOS. A graph, however, can have several PQLs. For example, one graph may need multiple PQLs if you want a separate PQL for each contract variant. You can link a PQL to any variants of its graph. And although many variants may use the same PQL, each variant can only have one linked PQL at a time.

1.1 PQL creation

  1. From your organization's Graphs page in GraphOS Studio, open the PQL page for a graph by clicking its PQL button:

You can also access a graph's PQLs from its settings page.

  1. From the PQL page:

    • If you haven't created any PQLs yet, click Create a Persisted Query List.
    • If you already have at least one PQL, click New List in the upper right.
  2. In the dialog that appears, provide a name and (optional) description for your PQL, then click Create.

    • At this point, your empty PQL has been created. The remaining dialog steps help with additional setup.
  3. The second dialog step (Link) enables you to link your new PQL to one existing variant of your graph.

    • You can optionally Skip this step and link variants later (covered in the next step).
  4. The third dialog step (Publish) displays your new PQL's unique ID and an example Rover CLI command for publishing operations to the PQL.

    • For now, you can leave the PQL empty. Client teams can publish operations to it in a later step.
    • Save this Rover CLI command so you can pass it on to your client teams when they publish operations.
  5. The fourth and final dialog step (Configure) displays the configuration options you apply to your router to begin using your PQL. We'll cover these in a later step.

  6. Click Finish to close the dialog and save your newly created PQL.

After you create a PQL, you can link it to one or more variants of your graph. Each router instance associated with a linked variant automatically fetches its PQL from GraphOS.

It's safe to link an empty or incomplete PQL to a variant because your router doesn't use its PQL for anything until you configure it to do so (covered in a later step).

  1. From the table on your graph's PQL page, open the ••• menu under the Actions column for the PQL you want to link.
    Click Link and Unlink Variants.

  2. In the dialog that appears, use the dropdown menu to select any variants you want to link your PQL to.

As a best practice, you can begin by linking your PQLs to a staging environment before moving on to a production one.

  1. Click Save.

After you link a PQL to a variant, GraphOS makes the PQL available in Uplink, the service that delivers configurations to your router at runtime. Once configured, the router polls Uplink to ensure it uses the most up-to-date PQL for linked variants.

2. Router configuration

The GraphOS Router is the key component that enforces safelisting.

Router security levels

3. Operation registration

Registering operations to a PQL has two steps:

  1. Generating persisted query manifests (PQM) using client-specific tooling
  2. Publishing PQMs to the PQL using the Rover CLI tool

Building both of these into your CI/CD pipeline incorporates new operations automatically whenever you release a new client app version.

3.1 Generate persisted query manifests

Once a PQL exists in GraphOS, client teams can start publishing operations to it. To do so, you must generate JSON manifests of the operations to publish. You generate a separate manifest for each of your client apps.

json title="persisted-queries.json"
{
  "format": "apollo-persisted-query-manifest",
  "version": 1,
  "operations": [
    {
      "id": "dc67510fb4289672bea757e862d6b00e83db5d3cbbcfb15260601b6f29bb2b8f",
      "body": "query UniversalQuery { __typename }",
      "name": "UniversalQuery",
      "type": "query"
    },
    {
      "id": "f11e4dcb28788af2e41689bb366472084aa1aa1e1ba633c3d605279cff08ed59",
      "body": "query FragmentedQuery { post { ...PostFragment } }  fragment PostFragment on Post { id title }",
      "name": "FragmentedQuery",
      "type": "query"
    }
  ]
}

You perform manifest generation in your CI/CD pipeline. Doing so automatically incorporates new operations when you release a new client app version.

Generation methods

Apollo Client for Web, Kotlin, and iOS each provide a mechanism for generating a manifest file from your app source. Apollo also supports manifests generated by the Relay compiler.

If your client app uses another GraphQL client library, you can build your own mechanism for generating operation manifests. See the expected manifest format.

See the instructions for your client library:

Apollo Client Web

  1. In your app's project, install the @apollo/generate-persisted-query-manifest package as a development dependency:

    bash showlinenumbers=false
    npm install --save-dev @apollo/generate-persisted-query-manifest

    This package includes a CLI command to generate a manifest file from your application source.

  2. Generate your first manifest with the following command:

    bash showlinenumbers=false
    npx generate-persisted-query-manifest
    • If the command succeeds, your manifest is written to persisted-query-manifest.json.
    • If the command fails (or if your manifest doesn't include all the operations you expect it to), you can configure the command's behavior using the options described in the package README.

See the full Apollo Client persisted queries guide for detailed instructions.

Apollo Kotlin

Manifest generation requires Apollo Kotlin 3.8.2 or later.

To generate an operation manifest with Apollo Kotlin, you modify your project's Gradle plugin configuration to generate a manifest in addition to the standard Kotlin source for your operations:

kotlin
apollo {
  service("myapi") {
    packageName.set("com.example.myapi")
    operationManifestFormat.set("persistedQueryManifest") //highlight-line
  }
}

The manifest will be generated in build/generated/manifest/apollo/myapi/persistedQueryManifest.json

See the full Apollo Kotlin persisted queries guide for detailed instructions.

Apollo iOS

Manifest generation requires Apollo iOS 1.4.0 or later.

To generate an operation manifest with Apollo iOS, you use the same code generation engine that you use to generate Swift code for each of your operations. Specifically, you modify the engine's file output configuration to include the output of an operationManifest.

See the full Apollo iOS persisted queries guide for detailed instructions.

Relay compiler

The Rover CLI has a built-in capability to publish operation manifests generated by the Relay compiler. Refer to Relay's documentation for instructions on generating manifests.

3.2 Publish manifests to the PQL

4. Client updates

With your manifest published and the router configured, you can update your clients to use registered operations IDs. Organizations can do this one client at a time as client teams publish client-specific PQMs to the PQL.

This step provides performance benefits but isn't necessary for safelisting. You can continue to use full operation strings rather than operation IDs in safelisting mode.

To execute operations using their PQL-specified ID instead of full operations strings, clients can use the same protocol used for automatic persisted queries (APQ).

Here's the JSON body of a request to execute an operation by its ID:

json
{
  "variables": null,
  "extensions": {
    "persistedQuery": {
      "version": 1,
      "sha256Hash": "PQL_ID_HERE"
    }
  }
}

If executing an operation that includes GraphQL variables, specify them with the variables property.

Apollo's mobile clients let you use the same mechanism for executing persisted queries operations as APQs.
Refer to their persisted query documentation for implementation details.

With Apollo Client Web, sending persisted queries by ID requires you to use an additional package at runtime alongside @apollo/client's built-in createPersistedQueryLink. Apollo Client Web requires this package to ensure that the ID sent at runtime matches the ID generated by generate-persisted-query-manifest. Mobile clients have a more deterministic approach to formatting operations and, thus, don't need additional support.

Refer to the Apollo Client Web's persisted query documentation for implementation details.

Incremental adoption path

Persisted queries' tiered security levels let you adopt an incremental approach rather than simultaneously requiring all clients to send requests via registered operations IDs. You can follow these steps for incremental adoption:

  1. Identify the first client you want to implement persisted queries with. It could be the client or team you're most comfortable with or the one most comfortable with GraphOS.

  2. Follow all implementation steps for your chosen client:

  3. Continue to monitor your router logs: once you consistently see that unregistered operations are being logged and registered ones aren't, you've completed the setup for this client! 🎉

If safelisting is your goal, you'll need to coordinate across client teams to complete these steps for each of your client apps.

Once your router's logs are completely clear of unexpected operations, you can configure your router to use safelisting mode. Then, to reap the performance benefits, update your client apps to use operation IDs rather than full operation strings.

Once you've confirmed all client apps use IDs, you can move to the most restrictive security level: safelisting with IDs only.
This security level enforces the performance benefit of using operation IDs rather than full operation strings. If you're content with the safelisting aspect of persisted queries with only optional performance benefits, you don't need to enable it.

Coordinate with client teams

Once you've followed the implementation steps for one client, you can coordinate across all your client teams:

  1. Identify all the client apps that execute operations against your router, and the GraphQL client libraries that those apps use.
    • Before you enable safelisting in your router, your client apps must start publishing their operations to your PQL.
  2. Communicate to your client development teams that adopting persisted queries will require adding tooling to their CI/CD pipeline.
  3. Identify which team members will assist with adding tooling to their respective CI/CD pipelines.
mermaid
graph LR;

  subgraph "CI/CD"
  webClient("Web client<br/>build");
  androidClient("Android client<br/>build");
  iosClient("iOS client<br/>build");
  end

  subgraph "GraphOS"
  pql[[Persisted<br/>Query List]];
  end

  webClient & androidClient & iosClient -->|Publishes<br/>operations|pql

Guide each client team to follow the implementation steps presented in the incremental adoption path.

Persisted query list management

From the Persisted Query Lists page, you can perform the following actions by clicking the ••• menu under the Actions column on the right of any PQL:

  • Download the list as a JSON file
  • Publish operations
  • Update the PQL's name and description
  • Link and unlink variants
  • Delete the PQL entirely

The Publish operations action provides the Rover CLI command to do so.

Operation management

You can add new operations to a PQL by using the Rover CLI, and you can delete operations from the PQL's page in GraphOS Studio. Since every operation should have a unique ID, you can't update existing operations—if you try to publish a revised operation body for an existing operation ID, Rover returns an error.

Adding operations

To add new operations to a PQL, you need to publish an updated manifest using the Rover CLI. If the manifest you're publishing doesn't include an operation in the PQL, this does not delete that operation from the PQL. Each manifest publication only adds any new operations to the PQL.

Deleting operations

If you want to delete an operation, you must do so from Studio. From the Persisted Query Lists page, click a persisted query list to open it. Then, click the ••• menu under the Actions column next to a particular operation and select Delete.

You should only delete operations that are problematic and shouldn't be executed. Even for such operations, it's important to recognize that operation deletions can cause application errors for legitimate clients, depending on your router's security level and if the client is sending full operation strings or operation IDs.

  • Regardless of security level, if a client sends an operation ID of a deleted operation, the router rejects the operation.
  • If you enabled safelisting, the router rejects any operations you deleted from the PQL but that your clients still perform, whether clients send operation IDs or full operation strings for the deleted operation.
  • When the router allows operation IDs or is in audit mode, if a client sends the full operation string of a deleted operation, the router executes it.

Although you can't undo operation deletions directly via the Studio UI, you can always republish a deleted operation using the Rover CLI.

Manifest format

You only need to read this section if you're building your own tooling to generate persisted query manifests.

A persisted query manifest has the following minimal structure:

json title="persisted-queries-manifest.json"
{
  "format": "apollo-persisted-query-manifest",
  "version": 1,
  "operations": [
    {
      "id": "dc67510fb4289672bea757e862d6b00e83db5d3cbbcfb15260601b6f29bb2b8f",
      "body": "query UniversalQuery { __typename }",
      "name": "UniversalQuery",
      "type": "query"
    }
  ]
}

Manifest properties are documented below.

Top-level properties

Property Description
###### format This value is currently always apollo-persisted-query-manifest.
###### version This value is currently always 1.
###### operations An array of objects describing the individual GraphQL operations to publish.

For details, see Per-operation properties. |

Per-operation properties

Each entry in a manifest's operations array is a JSON object that describes a single GraphQL operation to publish:

json
{
  "id": "dc67510fb4289672bea757e862d6b00e83db5d3cbbcfb15260601b6f29bb2b8f",
  "body": "query UniversalQuery { __typename }",
  "name": "UniversalQuery",
  "type": "query"
}

Each operation object has the following properties:

Property Description
###### id The unique ID to use for the operation in your PQL.

This value must be unique among operations in the PQL. It can match a previously published operation as long as the operation's body remains the same. If you try to publish an operation with the same id as an existing operation but a different body, manifest publication throws an error. GraphOS interprets this as an attempt to overwrite the existing PQL entry with a new body, which would change the behavior of existing deployed clients.

To ensure uniqueness, tooling should generate this value based on the operation body. For details, see Generating IDs. |
| ###### body | The complete query document for the operation. Includes the definition of the operation itself, along with accompanying fragment definitions. The router executes this string as the query document when a client sends the corresponding ID or matching operation. For details, see Ensuring consistent operation documents. |
| ###### name | The operation's name. Must match the name specified in body.

This value does not need to be unique among operations in the PQL. Often, different clients execute slightly different operations with the same name, and those operations each require a separate entry in the PQL. |
| ###### type | The type of GraphQL operation. Always one of the following values:

  • query
  • mutation
  • subscription |

Generating IDs

When generating operation IDs for a manifest, you should use a value that's unique to each operation, such as the query document's cryptographic hash. Apollo's manifest generation tools use the base16 representation of the document's SHA256 hash, which is the same format used for APQ.

By generating identifiers based on query documents this way, you ensure that different operations always have different IDs. ID uniqueness prevents unexpected collisions in your PQL. It also allows the router to execute operations both by full operation strings and PQL-specified IDs.

Never use an operation's name for its PQL ID. Different clients (or even different versions of the same client) might execute different operations with the same name, and all those distinct operations should be present in your PQL.

Ensuring consistent operation documents

Whenever a client sends an operation string to a router with safelisting enabled, the router checks for that operation string's presence in its persisted query list.

When comparing an incoming freeform GraphQL document to the registered operations in its PQL, the router ignores some aspects of the document that have no semantic impact:

  • Ignored tokens such as white space, comments, and commas are ignored.
  • The order of top-level definitions (operation and fragment definitions) is ignored. This means that when assembling a full GraphQL document from its operation and fragments, there's no need to ensure that fragments are put in the same order at build time and at run time.

However, all other details of the document must match. For example, field order, argument order, $variable names, alias names, string and numeric literals, and the presence of __typename fields must match between the incoming freeform GraphQL document and the document in the persisted query list.

Prior to Router v1.28, safelisting required the incoming document to match the document in the safelist precisely, including white space, comments, and top-level definition order.

For example, most applications treat responses from the following queries equivalently, but the router would reject the client operation because it doesn't match the PQL entry exactly. (The operations do semantically differ because GraphQL servers return fields in the order requested, even though most applications ignore the order of object fields in JSON.)

graphql title="pql entry"
query GetBooks {
  books {
    publishDate
    title
  }
}
graphql title="client operation"
query GetBooks {
  books {
    #highlight-start
    title
    publishDate
    #highlight-end
  }
}

Ordering differences (other than the order of top-level definitions) between a registered operation and the operation a client sends can similarly cause the router to reject client operations, even if they have no semantic impact on the operation.

graphql title="pql entry"
query GetBooks($limit: Int, $offset: Int) {
  books(limit: $limit, offset: $offset) {
    title
  }
}
graphql title="client operation"
query GetBooks($limit: Int, $offset: Int) {
  #highlight-start
  books(offset: $offset, limit: $limit) {
    #highlight-end
    title
  }
}

The router ignores top-level definition order and ignored tokens to make it easier to build tools that generate persisted query manifests whose contents match what will be sent at runtime. If your use case requires further normalization steps to be applied when comparing incoming opportunities to the safelist, contact Apollo Support; we are open to adding further normalization as an opt-in feature.

To ensure that you generate manifest entries correctly, it's important to note that your app's client library may modify the operation strings you define in your source before executing those corresponding operations. For example, by default, all Apollo Client libraries add the __typename field to every object in a query if that field isn't already present:

graphql title="source-defined query"
query GetBooks {
  books {
    author
    title
  }
}
graphql title="client-executed query"
query GetBooks {
  books {
    author
    title
    __typename #highlight-line
  }
}

The manifest generation tools for Apollo Client libraries all account for this default behavior.

If you're building your own manifest generation tool, ensure it accounts for any such operation changes in your chosen client library. Otherwise, the router will reject your app's operations due to an operation string mismatch if safelisting is enabled.

Similarly, if your clients execute operations by providing their PQL-specified ID, they might execute an operation without the augmentation added by your client library if you don't account for these operation changes.


File: src/content/graphos/basics/operations/subscriptions.mdx


title: GraphQL Subscriptions in Cloud Supergraphs subtitle: Real-time data delivery across your services

Cloud supergraph support for GraphQL subscriptions is currently in preview.

You can also use subscriptions with an Enterprise self-hosted supergraph. See the GraphOS Router documentation.

Cloud supergraphs provide preview support for GraphQL subscription operations:

graphql
subscription OnStockPricesChanged {
  stockPricesChanged {
    symbol
    price
  }
}

With a cloud supergraph, you can add Subscription fields to the schema of any subgraph that supports the graphql-transport-ws WebSocket protocol:

graphql title="stocks.graphql"
type Subscription {
  stockPricesChanged: [Stock!]!
}

Clients can then execute subscriptions on your cloud router, which executes them on your subgraphs.

To use subscriptions with your cloud supergraph, you must first complete certain prerequisites.

What are subscriptions for?

How subscriptions work

Walk through an example.

Prerequisites

Before you add Subscription fields to your subgraphs, do all the following in the order shown to prevent errors:

  1. Make sure you've created a cloud supergraph and connected your GraphQL API to it!

  2. Update your supergraph's build pipeline to use Apollo Federation 2.4 or later.

    • Previous versions of Apollo Federation don't support subscription operations.
  3. If your subgraph schemas specify an Apollo Federation version, modify them to use Apollo Federation 2.4 or later:

    graphql title="stocks.graphql"
    extend schema
      @link(
        url: "https://specs.apollo.dev/federation/v2.4" #highlight-line
        import: ["@key", "@shareable"]
      )
    
    type Subscription {
      stockPricesChanged: [Stock!]!
    }
    • You can skip modifying subgraph schemas that don't define any Subscription fields.
  4. In each subgraph with subscriptions, make sure the subgraph uses the graphql-transport-ws WebSocket protocol for subscriptions.

  5. In each subgraph with subscriptions, make sure the subgraph hosts its subscriptions WebSocket endpoint at the path /ws.

    • If your WebSocket endpoint is currently hosted at a different path, you can add /ws as an additional path instead of removing the original path. This is helpful if legacy clients will continue executing subscriptions on your subgraph directly using the original path.
  6. Deploy your updated subgraphs.

After you complete these prerequisites, you begin executing subscriptions on your cloud router.

Default configuration

Subscriptions are enabled automatically for GraphOS Cloud with the following default router configuration:

yaml
subscription:
  enabled: true
  mode:
    passthrough:
      all:
        path: /ws

Example execution

Let's say our supergraph includes the following subgraphs and partial schemas:

graphql title="products subgraph"
type Product @key(fields: "id") {
  id: ID!
  name: String!
  price: Int!
}

# highlight-start
type Subscription {
  productPriceChanged: Product!
}
#highlight-end
graphql title="reviews subgraph"
type Product @key(fields: "id") {
  id: ID!
  reviews: [Review!]!
}

type Review {
  score: Int!
}

A client can execute the following subscription against our router:

Remember, clients execute subscriptions against your router over HTTP!

Apollo Client for Web, Kotlin, and iOS all support HTTP-based subscriptions.

graphql
subscription OnProductPriceChanged {
  productPriceChanged {
    # Defined in Products subgraph
    name
    price
    reviews {
      # Defined in Reviews subgraph!
      score
    }
  }
}

When our router receives this operation, it executes a corresponding subscription operation against the Products subgraph (over a new WebSocket connection):

graphql
subscription {
  productPriceChanged {
    id # Added for entity fetching
    name
    price
    # Reviews fields removed!
  }
}
  • This operation adds the Product.id field. The router needs @key fields of the Product entity to merge entity fields from across subgraphs.
  • This operation removes all fields defined in the Reviews subgraph, because the Products subgraph can't resolve them.

At any point after the subscription is initiated, the Products subgraph might send updated data to our router. Whenever this happens, the router does not immediately return this data to the client, because it's missing requested fields from the Reviews subgraph!

Instead, our router executes a standard GraphQL query against the Reviews subgraph to fetch the missing entity fields:

graphql
query {
  _entities(representations: [...]) {
    ... on Product {
      reviews {
        score
      }
    }
  }
}

After receiving this query result from the Reviews subgraph, our router combines it with the data from Products and returns the combination to the subscribing client.

Trying subscriptions with `curl`

To quickly try out HTTP-based subscriptions without setting up an Apollo Client library, you can execute a curl command against your cloud router with the following format:

bash title="example curl request" showlinenumbers=false
curl 'https://main--my-org-supergraph.apollographos.net/graphql' -v \
  -H 'accept: multipart/mixed; boundary="graphql"; subscriptionSpec=1.0, application/json' \
  -H 'content-type: application/json' \
  --data-raw '{"query":"subscription OnProductPriceChanged { productPriceChanged { name price reviews { score } } }","operationName":"OnProductPriceChanged"}'

This command creates an HTTP multipart request and keeps an open connection that receives new subscription data in multiple response parts:

text showlinenumbers=false disablecopy=true
--graphql
content-type: application/json

{}
--graphql
content-type: application/json

{"payload":{"data":{"productPriceChanged":{"name":"Croissant","price":400,"reviews":[{"score":5}]}}}}
--graphql
content-type: application/json

{"payload":{"data":{"productPriceChanged":{"name":"Croissant","price":375,"reviews":[{"score":5}]}}}}
--graphql
content-type: application/json

{"payload":{"data":{"productPriceChanged":{"name":"Croissant","price":425,"reviews":[{"score":5}]}}}}
--graphql--

This example subscription only emits three events and then directly closes the connection.

For more information on this multipart HTTP subscription protocol, see this article.