An open API service indexing awesome lists of open source software.

https://github.com/metrue/edgeql

GraphQL on Edge
https://github.com/metrue/edgeql

Last synced: about 1 month ago
JSON representation

GraphQL on Edge

Awesome Lists containing this project

README

        

# EdgeQL

Effortlessly craft GraphQL APIs on the Edge, designed to thrive across various JavaScript runtimes.

| Runtime | Status | Example |
| ------------- | ------------- | ------------- |
| Cloudflare Workers | :white_check_mark: | [cloudflare](examples/cloudflare) |
| Node | :white_check_mark: | [node](examples/node) |
| Bun | :white_check_mark: | [Bun](examples/bun) |
| Deno | :white_large_square: Pending | |
| Vercel | :white_large_square: Pending | |

## EdgeQL on JavaScript Runtimes

### Node

```javascript
import { NodeEdgeQL } from 'edgeql/node'

const app = new NodeEdgeQL()

app.handle(`
type Query {
hello: String
}
`, (ctx) => {
return `hello from EdgeQL on ${ctx.runtime.runtime}`
})

app.listen({port: 4000}, ({address, family, port}) => {
console.log(address, family, port)
})
```

### Bun

```typescript
import { EdgeQL } from 'edgeql'
import type { Context } from 'edgeql'

const app = new EdgeQL()

app.handle(`
type Query {
hello: String
}
`, (_ctx: Context) => {
return 'hello from EdgeQL on Bun'
})

const port = Bun.env['PORT'] ? parseInt(Bun.env['PORT']) : 3000
console.log(`Running at http://localhost:${port}`)

export default {
port,
fetch: app.fetch
}
```

### Cloudflare Workers

```typescript
import { EdgeQL } from 'edgeql'
import type { Context } from 'edgeql'

const app = new EdgeQL()

app.handle(
`
type Query {
whereami: String
}
`,
(ctx: Context) => {
return `EdgeQL is running on ${ctx.runtime.runtime}`
})
```

## Schema Design Approaches

EdgeQL supports both Schema-First and Code-First.

* Schema First

```typescript
import { EdgeQL } from 'edgeql'

const app = new EdgeQL()
const schema = `
type Query {
hello: String
}
`
app.handle(schema, (ctx: Context) => 'world')

export default app
```

* Code First

```typescript
import { EdgeQL } from 'edgeql'
import type { Context } from 'edgeql'
import {
GraphQLSchema,
GraphQLObjectType,
GraphQLString,
} from 'graphql'

const app = new EdgeQL()

const helloworld: GraphQLSchema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: {
helloworld: {
type: GraphQLString,
resolve: (parent: any, args: any, ctx: Context, info: any) => {
return 'helloworld, EdgeQL'
},
},
},
})
})

app.handle(helloworld)

export default app
```

## Middlewares

EdgeQL adopts the same middleware style like Koa, middleware are simple functions which return a `MiddlewareFunction` with signature (ctx, next). When the middleware is run, it must manually invoke `next()` to run the "downstream" middleware.

For example if you wanted to track how long it takes for a request to propagate through EdgeQL by adding an `X-Response-Time` header field the middleware would look like the following:

```typescript
async function responseTime(ctx: Context, next: Next) {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
}

app.use(responseTime);
```

The builtin middlewares are,

* [JWT](src/middleware/jwt)
* [GraphiQL](src/middleware/graphiql)
* [CORS](src/middleware/cors)
* [wallclock](src/middleware/wallclock)