Skip to content

Instantly share code, notes, and snippets.

@Wallacy
Last active January 29, 2023 16:33
Show Gist options
  • Save Wallacy/4ad0d9b1ac8d36be8f731c60b15945c7 to your computer and use it in GitHub Desktop.
Save Wallacy/4ad0d9b1ac8d36be8f731c60b15945c7 to your computer and use it in GitHub Desktop.
Apollo Server + Cloudflare Workers
import { ApolloServerBase, Config, gql } from 'apollo-server-core'
export class ApolloServer extends ApolloServerBase {
protected override serverlessFramework(): boolean {
return true
}
public async createHandler() {
await this.ensureStarted()
return async (request: Request) => {
const url = new URL(request.url)
const query =
request.method === 'POST'
? await request.json()
: {
query: url.searchParams.get('query'),
variables: url.searchParams.get('variables'),
operationName: url.searchParams.get('operationName'),
extensions: url.searchParams.get('extensions'),
}
const resp = await this.executeOperation(query)
// TODO: ajustar para apenas em desenvolvimento
const headers = {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
...resp.http.headers,
}
delete resp.http
const body = JSON.stringify(resp)
return new Response(body, { headers })
}
}
}
const createHandler = async (config: Config) => {
const handler = new ApolloServer(config).createHandler()
return await handler
}
export { gql, createHandler }
// eslint-disable-next-line @typescript-eslint/no-var-requires
export const Buffer = require('buffer/').Buffer
import { build } from 'esbuild'
// ...
build({
entryPoints: ['server/src/worker.ts'],
outfile: 'dist/worker.mjs',
target: 'es2021',
format: 'esm',
minify: true,
bundle: true,
logLevel: 'info',
color: true,
define: { global: 'globalThis' },
external: ['https', 'os', 'zlib', 'crypto'],
inject: ['./buffer.ts'],
})
// ...
import { createHandler } from './apollo'
import config from './schemas'
type Awaited<T> = T extends PromiseLike<infer U> ? U : T
let handler: Awaited<ReturnType<typeof createHandler>>
const assetHandler = async () => {
if (!handler) {
handler = await createHandler(config)
}
}
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url)
await assetHandler()
if (url.pathname.startsWith('/graphql')) {
return handler(request)
}
// other routes
// tip: itty-router
return new Response('An unexpected error occurred', { status: 500 })
},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment