aboutsummaryrefslogtreecommitdiff

@eol/gq

A batteries-included GraphQL toolkit for Deno, wrapping graphql-js and @graphql-tools/schema with the bits most APIs end up reaching for anyway: a Fetch-compatible HTTP handler, a cached gql tag, a .graphql file loader, and a cleaned-up GraphQL Playground.

Install

Published on JSR as @eol/gq.

deno add jsr:@eol/gq

Or import directly:

import { executeSchema, gql, GraphQLHTTP } from "jsr:@eol/gq";

Quick start

import { executeSchema, gql, GraphQLHTTP } from "@eol/gq";

const schema = executeSchema({
  resolvers: {
    Query: {
      hello: (_, { name }) => `hello, ${name ?? "world"}`
    }
  },
  typeDefs: gql`
    type Query {
      hello(name: String): String
    }
  `
});

Deno.serve(
  { port: 8000 },
  GraphQLHTTP({ graphiql: true, schema })
);

Visit http://localhost:8000 in a browser for the Playground, or POST a query to the same URL.

Loading schemas from .graphql files

Use importQL to read an entry file and resolve its imports into a single SDL string.

Explicit imports

# schema/schema.graphql
# import "./post.graphql"
# import "./user.graphql"

type Query {
  me: User
  posts: [Post!]!
}
import { executeSchema, gql, importQL } from "@eol/gq";

const typeDefs = gql(await importQL("schema/schema.graphql"));
const schema = executeSchema({ resolvers, typeDefs });

Dynamic imports

Drop # DYNAMIC_IMPORTS in your entry file and every .graphql file found one level below <cwd>/schema/ gets inlined at that marker:

schema/
  schema.graphql   # contains: # DYNAMIC_IMPORTS
  post/
    post.graphql
  user/
    user.graphql

API

All symbols are re-exported from the package root (@eol/gq).

GraphQLHTTP(options)

Returns a (request) => Promise<Response> handler. Pluggable into Deno.serve, oak, hono, or anything else Fetch-shaped.

Options:

Option Type Description
schema GraphQLSchema Required. Executable schema.
context (req) => Ctx \| Promise<Ctx> Builds the resolver context per request.
graphiql boolean Serve the Playground on GET + Accept: text/html.
headers HeadersInit Extra headers merged into every response.
playgroundOptions Omit<RenderPageOptions, "endpoint"> Passthrough options for the Playground renderer.

executeSchema(config)

Re-export of @graphql-tools/schema’s makeExecutableSchema, renamed for brevity.

gql (tagged template)

Parses a GraphQL string into a DocumentNode. Results are cached by normalized source, and embedded DocumentNode interpolations are inlined from their original source.

Companion knobs:

  • disableExperimentalFragmentVariables()
  • disableFragmentWarnings()
  • enableExperimentalFragmentVariables()
  • resetCaches()

importQL(path)

Reads a .graphql file and resolves its imports. See Loading schemas from .graphql files.

runHttpQuery(params, options, request)

Low-level executor that GraphQLHTTP delegates to. Use it if you’re rolling your own transport but still want the context wiring.

Types

GQLOptions, GQLRequest, GraphQLParams, GraphQLHandler, plus the Playground types (RenderPageOptions, MiddlewareOptions, ISettings, EditorColours, Tab, Theme, CursorShape, IntrospectionResult).

Features

  • Import *.graphql files — explicit and dynamic — via importQL.
  • GraphiQL/Playground code cleaned up; SVGs redrawn so they actually make sense.
  • Ships typed; passes deno check entry.ts with no fuss.
  • Zero build step — it’s Deno, you just import it.

TODO

  • Add a runnable example.
  • Replace React Playground with Svelte/SvelteKit.
  • Take over the world (real world, metaverse, or yggdrasil, whichever comes first).

License

MIT