Skip to content
This repository has been archived by the owner on Jun 22, 2024. It is now read-only.

feat: google cloud run example with graphql #45

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions cloud/google-cloud-run/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM node:20 as base
WORKDIR /usr/app

FROM base as build
WORKDIR /usr/app
ENV NODE_ENV=production
ENV CI=true
COPY package.json package-lock.json ./
RUN npm install --production
COPY . ./

FROM node:20 as production
WORKDIR /usr/app
ENV NODE_ENV=production
COPY --from=build /usr/app ./
CMD ["node", "index.js"]
35 changes: 35 additions & 0 deletions cloud/google-cloud-run/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Google Cloud Run Example

This example shows how to deploy a simplified GraphQL API to
[Google Cloud Run](https://cloud.google.com/run).

## Prerequisites

Check out the
[Get started](https://cloud.google.com/run/docs/quickstarts/build-and-deploy/deploy-nodejs-service)
guide on Google Cloud to set up the project.

## Deploy

```bash
gcloud run deploy example \
--source . \
--project=zentered \
--region=us-central1 \
--memory=256Mi \
--platform=managed \
--allow-unauthenticated \
--use-http2 \
--set-env-vars=VERSION=1.0.0
```

You can set environment variables for the Docker container with
`--set-env-vars`, `VERSION` is used as an example here.

## Next Steps

- Instead of building from source, you can use
[Cloud Build](https://cloud.google.com/build) for continous deployment from a
Git respository
- Cloud Build can create and push Docker images to
[Artifact Registry](https://cloud.google.com/artifact-registry)
28 changes: 28 additions & 0 deletions cloud/google-cloud-run/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Fastify from 'fastify'
import mercurius from 'mercurius'

function build(opts = {}) {
const fastify = Fastify(opts)

const schema = `
type Query {
add(x: Int, y: Int): Int
}
`

const resolvers = {
Query: {
add: async (_, { x, y }) => x + y
}
}

fastify.register(mercurius, {
schema,
graphiql: true,
resolvers
})

return fastify
}

export default build
6 changes: 6 additions & 0 deletions cloud/google-cloud-run/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const port = process.env.PORT || 3000
export const debug = process.env.DEBUG === 'true'
export const environment = process.env.NODE_ENV || 'development'
export const production = process.env.NODE_ENV === 'production'
export const development = process.env.NODE_ENV !== 'production'
export const appVersion = process.env.VERSION || '0.0.0'
40 changes: 40 additions & 0 deletions cloud/google-cloud-run/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import build from './app.js'
import { development, environment, production, port } from './config.js'

const host = development ? 'localhost' : '0.0.0.0'

const start = async () => {
// A custom logger, as Cloud Run does not need a transport configuration
const envToLogger = {
development: {
level: 'debug',
transport: {
target: 'pino-pretty',
options: {
ignore: 'pid,hostname'
}
}
},
production: true,
test: false
}

try {
const fastify = await build({
logger: envToLogger[environment] ?? true,
disableRequestLogging: production, // Cloud Run logs requests, no request logging is needed
http2: production // Enable HTTP2 for production
})
await fastify.listen({ port: port, host: host })
fastify.ready(() => {
console.log(`listening on ${JSON.stringify(fastify.server.address())}`)
console.log(fastify.printRoutes())
})
} catch (err) {
console.log(err)
// eslint-disable-next-line no-process-exit
process.exit(1)
}
}

start()
20 changes: 20 additions & 0 deletions cloud/google-cloud-run/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "google-cloud-run",
"version": "1.0.0",
"description": "",
"type": "module",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "node --test"
},
"keywords": [],
"author": "Patrick Heneise <[email protected]> (https://zentered.co)",
"dependencies": {
"fastify": "^4.17.0",
"mercurius": "^13.0.0"
},
"devDependencies": {
"pino-pretty": "^10.0.0"
}
}
24 changes: 24 additions & 0 deletions cloud/google-cloud-run/test/graphql.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict'

import test from 'node:test'
import assert from 'node:assert/strict'
import build from './../app.js'

test('/gaphql', async (t) => {
const app = build({ logger: false })
const expected = { data: { add: 2 } }
const query = `{
add(x:1,y:1)
}`

const response = await app.inject({
method: 'POST',
url: '/graphql',
body: { query: query }
})
const actual = await response.json()

assert.equal(response.statusCode, 200, 'returns a status code of 200')
assert.deepEqual(actual, expected)
await app.close
})