Automate deploying GraphQL APIs to Cloudflare Workers

24 Apr 2023

Let's begin with a basic GraphQL Yoga setup. I'll be using Cloudflare Workers but you can serve GraphQL however you want.

npx wrangler init hello-graphql

Next we'll install GraphQL and GraphQL Yoga:

npm i graphql graphql-yoga

If we now begin to construct the GraphQL Yoga server using createYoga and createSchema, we'll notice that when we define the resolvers we get absolutely no type safety.

import { createYoga, createSchema } from "graphql-yoga";

const schema = createSchema({
  typeDefs: /* GraphQL */ `
    type Query {
      cart(id: ID!): Cart!
    }

    type Cart {
      id: ID!
      totalItems: Int!
      items: [CartItem]
      subTotal: Money!
    }

    type CartItem {
      id: ID!
      name: String!
    }

    type Money {
      amount: Int!
      formatted: String!
    }
  `,
  resolvers: {
    Query: {
      cart: (_, { id }) => ({
        id,
        totalItems: 1,
        items: [{ id: "item-1", name: "Stickers" }],
        subTotal: {
          amount: 1000,
          formatted: "£10",
        },
      }),
    },
  },
});

interface Env {
  // Bindings
}

export default {
  fetch(request: Request, env: Env, ctx: ExecutionContext) {
    const yoga = createYoga({
      graphqlEndpoint: "/",
      landingPage: false,
      schema,
    });

    return yoga.fetch(request, env, ctx);
  },
};

Now we'll create the file .github/workflows/deploy.yml in our project with the following config that will invoke the GitHub Actions plugin:

name: Deploy

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: "Checkout repository"
        uses: actions/checkout@v3

We'll next be using the deploy script inside package.json, so make sure you have that:

{ "deploy": "wrangler publish" }

All that's left to do is tell the GitHub Action to install dependencies and deploy using Wrangler:

name: Deploy

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: "Checkout repository"
        uses: actions/checkout@v3
      - name: "Install dependencies"
        run: npm install
      - name: "Deploy to Cloudflare"
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        run: npm run deploy

Finally let's create the CLOUDFLARE_API_TOKEN value and add it to GitHub Actions as a secret value. Follow these instructions and make sure to give it permission to your worker. You might need to deploy manually first so it shows up.