Skip to main content

Distributed GraphQL with Apollo Router

The Apollo Router is a high-performance GraphQL router that runs a federated supergraph, which is a single graph composed of multiple underlying services. By distributing the router container across CloudFlow's network around the world your apps will be more responsive thanks to faster responses to their API calls. This tutorial shows you how to distribute the Apollo Router on CloudFlow.

note

Before starting, create a new CloudFlow Project and then delete the default Deployment and ingress-upstream Service to prepare the project for your new deployment.

Prerequisites

  • You need an Apollo Federation 2 project in Apollo Studio. Apollo's Federation 2 quickstart can guide you if you don't have one already.

Get Setup with Apollo

If you already have an Apollo Federation 2 project, then skip to the next step. Otherwise set on up by following Apollo's Federation 2 quickstart. You'll be leveraging sample data provided by Apollo.

Setup a ConfigMap for Router Configuration

Create a config.yaml as defined below. This ConfigMap configures the router to listen on port 80. Additional examples of what can be configured are here.

config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: apollo
labels:
name: apollo
data:
configuration.yaml: |
server:
listen: 0.0.0.0:80

Apply this ConfigMap resource to your Project with either the Kubernetes dashboard or kubectl apply -f configmap.yaml.

Create a Kubernetes Deployment for Apollo Router

Next, create a CloudFlow deployment for Apollo Router with a file apollo-router-deployment.yaml, substituting YOUR_APOLLO_KEY and YOUR_APOLLO_GRAPH_REF accordingly. YOUR_APOLLO_KEY is your personal API KEY for Apollo Studio. And YOUR_APOLLO_GRAPH_REF is a string along the lines of My-Graph-lypak@current, and is the reference for your federated graph.

This deployment direct CloudFlow to distribute the container you've pushed to Docker Hub.

apollo-router-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: apollo
name: apollo
spec:
replicas: 1
selector:
matchLabels:
app: apollo
template:
metadata:
labels:
app: apollo
spec:
containers:
- image: ghcr.io/apollographql/router:v1.0.0-alpha.3
imagePullPolicy: Always
name: apollo
args:
- --hot-reload
- --config
- /app/configuration.yaml
env:
- name: APOLLO_KEY
value: YOUR_APOLLO_KEY
- name: APOLLO_GRAPH_REF
value: YOUR_APOLLO_GRAPH_REF
volumeMounts:
- name: router-configuration
mountPath: /app/configuration.yaml
subPath: configuration.yaml
readOnly: true
resources:
requests:
memory: ".5Gi"
cpu: "500m"
limits:
memory: ".5Gi"
cpu: "500m"
volumes:
- name: router-configuration
configMap:
name: apollo

Apply this deployment resource to your Project with either the Kubernetes dashboard or kubectl apply -f apollo-router-deployment.yaml.

Expose the Service on the Internet

We want to expose the Apollo Server on the Internet. Create ingress-upstream.yaml as defined below.

ingress-upstream.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: ingress-upstream
name: ingress-upstream
spec:
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: apollo
sessionAffinity: None
type: ClusterIP

Apply this service resource to your Project with either the Kubernetes dashboard or kubectl apply -f ingress-upstream.yaml.

See the pods running on CloudFlow's network with kubectl get pods -o wide. The -o wide switch shows where your GraphQL API is running according to the default AEE location optimization strategy. Your GraphQL API will be optimally deployed according to traffic. In lieu of significant traffic, your deployment will be made to default locations.

Apollo pods

Try kubectl logs POD to see the log message reporting that the server is listening on port 4000.

Finally, follow the instructions that configure DNS and TLS.

Browse Your GraphQL API

Visit https://YOUR_ENVIRONMENT_HOSTNAME in your browser to play in the Apollo Sandbox. You may have multiple pods running in multiple locations, but your chosen hostname will route to the one that is physically closest.

Enter the following query:

query Query {
locations {
name
}
}

You'll see the following result: Apollo Router Response