Graph Environment Best Practices
Best practices and examples when using graph variants for multiple deployment environments
Learn CI/CD best practices and examples for using graph variants for multiple deployment environments.
In a typical deployment architecture, organizations set up multiple environments—such as development, pre-prod, and prod—with each having a separate Kubernetes cluster and database. They create separate CI/CD jobs for each environment or configure them to behave differently based on environment-specific variables. They use in GraphOS a dedicated graph variant for each environment, with each variant representing a specific copy of the graph for that environment.
The setup for a typical deployment architecture begins with code and schemas in source control. A CI/CD system both deploys code to a target deployment environment and publishes schemas to GraphOS, which then provides the schemas to a deployment environment:
Source control branches for variants
The source control branching model you use affects the branch in which the code for a graph variant is developed. Let's go over examples for a few common branching models.
Git flow (feature, develop, main)
In Git Flow, you typically have a develop
branch and a main
branch, where develop
contains the code under-development that hasn't necessarily been deployed to a production environment, and main
contains the production code.
In this setup, you can create two variants, mygraph@develop
and mygraph@main
, that correspond directly to the develop
and main
branches.
A feature/*
branch contains the code for a particular feature.
When a pull request is opened to merge feature/*
into develop
, a set of schema checks is executed to ensure this set of changes will not break the supergraph upon composing or publishing the changes.
Once the code is merged from feature/*
into develop
, a CI/CD job runs to deploy the changes to the development environment and publish the subgraph to the mygraph@develop
variant.
When the code in the develop
branch is ready for production, it is merged into main
, triggering a CI/CD job to deploy the changes to the production environment and publish the subgraph to the mygraph@main
variant.
In the deployment environments, your subgraphs and the GraphOS Router run with the router configured to pull from a specific variant.
Simplified feature branch flow (feature, main)
A branching model similar to Git Flow uses feature
and main
branches but doesn't use develop
. Instead, new features are branched directly off the main
branch, and when the code is completed, each feature
branch is merged directly into main
. In this model, main
represents the latest code but not necessarily what is deployed to production.
In this setup, you can still have two variants, mygraph@develop
and mygraph@main
, but the timing of when they are published differs slightly from Git Flow.
A feature/*
branch contains the code for a particular feature.
When a pull request is opened to merge feature/*
into main
, a set of schema checks is executed to ensure this set of changes will not break the supergraph upon composing or publishing the changes.
Once the code is merged from feature/*
into main
, a CI/CD job runs to deploy the changes to the development environment and publish the subgraph to the mygraph@develop
variant.
When the code in the main
branch is ready for production, a CI/CD job runs to deploy the changes to the production environment and publish the subgraph to the mygraph@main
variant.
In the deployment environments, your subgraphs and the GraphOS Router run with the router configured to pull from a specific variant.
Multi-branch flow (feature, develop, preprod, main)
In some cases, you might need multiple branches to accommodate multiple non-production environments. This can be achieved by expanding the Git Flow setup with additional variants tied to various branches.
In this setup, you would likely have a variant for each deployment environment (mygraph@develop
, mygraph@preprod
, mygraph@main
), each linked directly to the appropriate Git branches.
A feature/*
branch contains the code for a particular feature.
When a pull request is opened to merge feature/*
into develop
, a set of schema checks is executed to ensure these changes won't break the supergraph upon composing or publishing.
Once the code is merged from feature/*
into develop
, a CI/CD job runs to deploy the changes to the development environment and publish the subgraph to the mygraph@develop
variant.
When the code in the develop
branch is ready for pre-production verification, such as user acceptance testing, the code is merged into preprod
. Subsequently, a CI/CD job is run to deploy the changes to the pre-prod environment and publish the subgraph to the mygraph@preprod
variant.
Finally, when the code in the preprod
branch is ready for production, it is merged into main
, and a CI/CD job is run to deploy the changes to the production environment and publish the subgraph to the mygraph@main
variant.
In the deployment environments, your subgraphs and Router run with the router configured to pull from a specific variant.
Running subgraph checks
Using rover subgraph check
to run checks when opening a merge request is a great tool for ensuring that changes won't cause problems with the composition of your supergraph. Setting this up requires a CI/CD job to run against pull request events and execute the rover command on the updated schema.
Here is an example using GitHub Actions:
1name: Pull Request Check Code
2
3on: pull_request
4
5env:
6 APOLLO_KEY: ${{ secrets.APOLLO_KEY }}
7 APOLLO_VCS_BRANCH: ${{ github.head_ref }}
8 APOLLO_VCS_COMMIT: ${{ github.event.pull_request.head.sha }}
9
10jobs:
11 npm-build:
12 runs-on: ubuntu-latest
13 steps:
14 - uses: actions/checkout@v4
15
16 - uses: actions/setup-node@v3
17 with:
18 node-version: 18.x
19 cache: 'npm'
20
21 - run: npm ci
22
23 - run: npm run build
24 checks:
25 name: Rover Subgraph Check
26 runs-on: ubuntu-latest
27
28 steps:
29 - name: Checkout
30 uses: actions/checkout@v4
31
32 - name: Install Rover
33 run: |
34 curl -sSL https://rover.apollo.dev/nix/v0.8.1 | sh
35 echo "$HOME/.rover/bin" >> $GITHUB_PATH
36
37 - name: Rover Subgraph Check
38 run: |
39 rover subgraph check ${{ secrets.APOLLO_GRAPH_ID }}@develop \ # Specifying the variant here. This might also come from an environment variable, input, etc
40 --name subgraph-a \
41 --schema ./src/schema.graphql
Publishing schemas
To publish a schema from your CI/CD jobs to a GraphOS variant, you can use the rover subgraph publish
command.
Note that the
rover subgraph publish
command (as well as publishing through the Platform API) is rate limited to 400 requests per minute, per graph.
Here is an example using GitHub Actions:
1name: Manual Deploy
2
3on: workflow_dispatch
4
5env:
6 APOLLO_KEY: ${{ secrets.APOLLO_KEY }}
7 APOLLO_VCS_BRANCH: ${{ github.head_ref }}
8 APOLLO_VCS_COMMIT: ${{ github.event.pull_request.head.sha }}
9
10jobs:
11 deploy:
12 # Your deployment steps would go here!
13 publish:
14 name: Rover Subgraph Publish
15 runs-on: ubuntu-latest
16
17 steps:
18 - name: Checkout
19 uses: actions/checkout@v4
20
21 - name: Install Rover
22 run: |
23 curl -sSL https://rover.apollo.dev/nix/v0.8.1 | sh
24 echo "$HOME/.rover/bin" >> $GITHUB_PATH
25
26 - name: Rover Subgraph Publish
27 run: |
28 rover subgraph publish ${{ secrets.APOLLO_GRAPH_ID }}@develop \ # Specifying the variant here. This might also come from an environment variable, input, etc
29 --name subgraph-a \
30 --routing-url http://graphql.mygraph.svc.cluster.local:4000 \
31 --schema ./src/schema.graphql