- Docker installed for Docker deployment
- Kubernetes cluster and kubectl for Kubernetes deployment
- Helm installed for Kubernetes deployment
- Grafbase Access Token (if using schema registry, or dashboard analytics)
- Grafbase graph ref (if using schema registry), or a local federated schema file
- Locally built or downloaded extensions (from
grafbase extension install
) and a configuration file (grafbase.toml
) with an extensions section
Grafbase Gateway is a GraphQL federation gateway that can be extended with custom functionality through extensions. Extensions allow you to add custom resolvers, authentication logic, and more to your GraphQL API.
Extensions are implemented as WebAssembly components that are loaded by the gateway at runtime. The extensions are installed in a directory named grafbase_extensions
, which must be available to the gateway when it starts. Alternatively, you can define the extension to be in a specific path in grafbase.toml
under the extensions
section. This path must have a valid extension WebAssembly component, and the manifest file.
To set up a Grafbase Gateway with extensions, you need:
- The
grafbase-gateway
binary - A
grafbase_extensions
directory containing installed extensions - A configuration file (typically
grafbase.toml
) - Either environment variables to fetch the schema from Grafbase's registry, or a local federated GraphQL schema file
This approach uses the Schema Registry to fetch the graph schema based on a Graph Reference and Access Token. This method polls for changes to the schema automatically every ten seconds, and restarts the gateway with changes.
Create a Dockerfile
in the root of your project.
FROM ghcr.io/grafbase/gateway:0.38.0 # or later version!
# Create directories
WORKDIR /app
# Copy the configuration file
COPY grafbase.toml /app/grafbase.toml
# Copy the extensions directory if you have custom extensions
COPY grafbase_extensions /app/grafbase_extensions
# Set default command
CMD ["--config", "/app/grafbase.toml"]
Create a grafbase.toml
file in the root of your project.
[graph]
introspection = true
[network]
listen_address = "0.0.0.0:5000"
[extensions]
rest = "0.4"
Before building the Docker image, install the extensions:
grafbase extension install
This will create or update the grafbase_extensions
directory with the specified extensions.
Before deploying the gateway, create all subgraphs as needed, and publish them to the Schema Registry. For this simple example, we will create a subgraph that fetches country names from a public REST API.
Create a subgraph.graphql
in the root of your project:
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key", "@shareable"])
@link(url: "https://grafbase.com/extensions/rest/0.4.1", import: ["@restEndpoint", "@rest"])
@restEndpoint(
name: "restCountries",
baseURL: "https://restcountries.com/v3.1"
)
type Country {
name: String!
}
type Query {
listAllCountries: [Country!]! @rest(
method: GET
endpoint: "restCountries"
path: "/all"
selection: "[.[] | { name: .name.official }]"
)
}
Publish the subgraph to the Schema Registry:
grafbase publish \
--name restCountries \
your-org/your-graph@branch \
-m initx \
--virtual \
--schema subgraph.graphql
Create a compose.yml
in the root of your project:
services:
grafbase:
build: .
restart: always
environment:
GRAFBASE_GRAPH_REF: 'your-graph@branch'
GRAFBASE_ACCESS_TOKEN: 'your-access-token'
ports:
- '5000:5000'
The access token should be created in the Grafbase dashboard, and scoped to have access to the graph.
docker-compose up -d
This approach uses a local federated GraphQL schema file instead of fetching it from the Schema Registry. This step requires you to manually fetch the federated schema when it is updated. You can replace the schema file in the running container without restarting the gateway. The gateway will automatically reload the schema when it changes.
Add the following content to the compose.yml
file:
FROM ghcr.io/grafbase/gateway:0.38.0 # or later
# Create directories
WORKDIR /app
# Copy the configuration file
COPY grafbase.toml /app/grafbase.toml
# Copy the federated schema
COPY federated-graph.graphql /app/federated-graph.graphql
# Copy the extensions directory
COPY grafbase_extensions /app/grafbase_extensions
# Set default command
CMD ["--config", "/app/grafbase.toml", "--schema", "/app/federated-graph.graphql"]
Same as the previous example.
Same as the previous example.
Same as the previous example.
After successfully publishing a subgraph, fetch the federated schema using the following command:
grafbase schema your-org/your-graph@branch > federated-graph.graphql
version: '3'
services:
grafbase:
build: .
restart: always
ports:
- '5000:5000'
# keep the environment variables if you want dashboard
# analytics. remove, if you want to run the gateway
# totally air-gapped
environment:
GRAFBASE_GRAPH_REF: 'your-graph@branch'
GRAFBASE_ACCESS_TOKEN: 'your-access-token'
volumes:
# Mount the schema file as a volume for easy updates
- ./federated-graph.graphql:/app/federated-graph.graphql
docker-compose up -d
This method uses Helm to deploy the Grafbase Gateway that fetches the schema from the Schema Registry.
Create a custom values.yaml
file for Helm:
replicaCount: 2
image:
repository: ghcr.io/grafbase/gateway
tag: 0.38.0 # or later version
pullPolicy: Always
service:
type: ClusterIP
port: 80
targetPort: 5000
gateway:
externalSchema: true
externalConfig: false
config: |
[graph]
introspection = true
[network]
listen_address = "0.0.0.0:5000"
[extensions]
rest = "0.4"
secrets:
enabled: true
values:
GRAFBASE_GRAPH_REF: "your-graph@branch"
GRAFBASE_ACCESS_TOKEN: "your-access-token"
# Create a ConfigMap to store extensions
volumes:
- name: extensions
configMap:
name: grafbase-extensions
volumeMounts:
- name: extensions
mountPath: /app/grafbase_extensions
Install the extensions locally:
grafbase extension install
Create a ConfigMap from the extensions directory:
kubectl create configmap grafbase-extensions --from-file=grafbase_extensions/
Or define it in a YAML file:
apiVersion: v1
kind: ConfigMap
metadata:
name: grafbase-extensions
data:
# Content of each extension file, converted to base64
# This would be automatically populated when using the kubectl create command
helm install grafbase-gateway oci://ghcr.io/grafbase/helm-charts/gateway --version 0.2.5 -f values.yaml
This method uses a local federated GraphQL schema file stored in a ConfigMap.
Create a custom values.yaml
file for Helm:
replicaCount: 2
image:
repository: ghcr.io/grafbase/gateway
tag: 0.38.0 # or lateer
pullPolicy: Always
service:
type: ClusterIP
port: 80
targetPort: 5000
gateway:
externalSchema: true
externalConfig: false
config: |
[graph]
introspection = true
[network]
listen_address = "0.0.0.0:5000"
[extensions]
rest = "0.4"
args:
- --config
- /etc/grafbase/config/grafbase.toml
- --schema
- /etc/grafbase/schema/federated-graph.graphql
# Create volumes for config, schema, and extensions
volumes:
- name: schema
configMap:
name: grafbase-schema
- name: extensions
configMap:
name: grafbase-extensions
volumeMounts:
- name: schema
mountPath: /etc/grafbase/schema
- name: extensions
mountPath: /app/grafbase_extensions
Create ConfigMaps for the configuration, schema, and extensions:
# For the schema
kubectl create configmap grafbase-schema --from-file=federated-graph.graphql
# For extensions
grafbase extension install
kubectl create configmap grafbase-extensions --from-file=grafbase_extensions/
helm install grafbase-gateway oci://ghcr.io/grafbase/helm-charts/gateway --version 0.2.5 -f values.yaml
You can customize extensions by modifying your grafbase.toml
file. For example, to configure the JWT extension:
[extensions.jwt]
version = "1.0"
[extensions.jwt.config]
jwks.url = "https://example.com/.well-known/jwks.json"
jwks.issuer = "example.com"
jwks.audience = "my-project"
jwks.poll_interval = 60
[extensions.jwt.config.header]
name = "Authorization"
value_prefix = "Bearer "
Configure health checks in your grafbase.toml
:
[health]
enabled = true
listen = "0.0.0.0:9668"
path = "/health"
For production environments, you might want to set up telemetry:
[telemetry]
service_name = "my-federated-graph"
[telemetry.tracing]
enabled = true
sampling = 1
[telemetry.tracing.exporters.otlp]
enabled = true
endpoint = "http://my-otel-collector:4317"
protocol = "grpc"
timeout = 5
This guide has demonstrated how to deploy Grafbase Gateway with extensions in both Docker and Kubernetes environments. By following these instructions, you can set up a flexible and extensible GraphQL federation gateway that meets your specific needs, whether you're using Grafbase's Schema Registry or a local schema file.