An Apollo GraphQL server, built with Cloudflare Workers.
Whether you host your APIs on-prem, in the cloud, or you're deploying databases to Cloudflare directly, you can deploy a globally distributed GraphQL server with Cloudflare Workers.
Begin by cloning this repo and installing the dependencies:
$ git clone https://github.com/cloudflare/workers-graphql-server
$ npm install
You can begin running the project locally by running npm run dev
.
You'll need to configure your project's wrangler.toml
file to prepare your project for deployment. See the "Configuration" docs for a guide on how to do this.
The source for this project shows how to make requests to external APIs, using the PokeAPI as an example. You can run an example query to ensure it works after deployment:
query {
pokemon: pokemon(id: 1) {
id
name
height
weight
sprites {
front_shiny
back_shiny
}
}
}
Resolvers are defined in src/resolvers.ts
. You can also use Service Bindings to connect to other Workers services, and use them inside your resolvers.
If you change your GraphQL schema at src/schema.graphql
, you'll need to run npm run codegen
to update the generated types in src/generated/graphql.ts
. This ensures that you can correctly import and type your resolvers.
You can optionally configure your graphQLOptions
object in src/index.js
:
const graphQLOptions = {
baseEndpoint: '/',
enableSandbox: true,
forwardUnmatchedRequestsToOrigin: false,
cors: true,
kvCache: false,
}
Make requests to your GraphQL server by sending POST
requests to the baseEndpoint
(e.g. graphql-on-workers.signalnerve.com/
).
By default, the Apollo Sandbox is enabled. This allows you to test your GraphQL in a web GUI without needing to write any client code.
If you run your GraphQL server on a domain already registered with Cloudflare, you may want to pass any unmatched requests from inside your Workers script to your origin: in that case, set forwardUnmatchedRequestToOrigin
to true (if you're running a GraphQL server on a Workers.dev subdomain, the default of false
is fine).
While configuring your server, you may want to set the debug
flag to true
, to return script errors in your browser. This can be useful for debugging any errors while setting up your GraphQL server, but should be disabled on a production server.
By default, the cors
option allows cross-origin requests to the server from any origin. You may wish to configure it to whitelist specific origins, methods, or headers. This is done by passing an object to cors
, which is based on the hono/cors middleware:
const graphQLOptions = {
// ... other options ...
cors: {
origin: 'http://example.com',
allowHeaders: ['X-Custom-Header', 'Upgrade-Insecure-Requests'],
allowMethods: ['POST', 'GET', 'OPTIONS'],
exposeHeaders: ['Content-Length', 'X-Kuma-Revision'],
maxAge: 600,
credentials: true,
},
}
This project includes support for using Workers KV as a cache in your resolvers. To use caching in your project, create a new KV namespace, and in wrangler.toml
, configure your namespace, calling it KV_CACHE
(note that this binding name is required, currently):
# wrangler.toml
[[kv-namespaces]]
binding = "KV_CACHE"
id = "$myId"
With a configured KV namespace set up, you can opt-in to KV caching by changing the kvCache
config value in graphQLOptions
(in index.js
) to true
.
In any resolver function, you can access the cache
object, which is an instance of KVCache
. You can use .get
and .set
to interact with the cache:
pokemon: async (_parent, { id }, { cache }) => {
if (cache) {
const pokemon = await cache.get(id)
if (pokemon) {
return pokemon
}
}
// You can hook into any util functions, API wrappers, or other
// code that you need to resolve your query.
const pokemonData = await PokemonAPI.getPokemon(id)
// You can also cache the data if you need to, with an optional TTL
if (cache) await cache.set(id, pokemonData, { ttl: 60 })
return pokemonData
},
This project is heavily based on the @as-integrations/cloudflare-workers package, which is a great tool for building GraphQL servers with Cloudflare Workers.
It is built with Hono, a simple and powerful web framework for Cloudflare Workers.
This project is licensed with the MIT License.