fresh_graphql
GraphQL development for Deno Fresh.
Live Demo
graphql-yogaapollo-server(soonTM)
Why fresh_graphql?
- Familiar developer experience with
freshprojects. deno deployhas no dynamic imports.tRPCdoesnāt support deno (yet).
Installation
fresh_graphql hooks into the dev.ts lifecycle of fresh,
create a fresh project
if you havenāt done so.
You need to patch 3 files from an existing fresh project:
1. import_map.json
Versions are removed for clarity, should be compatible with fresh@^1.1.1.
{
"imports": {
"$fresh/": "https://deno.land/x/fresh/",
+ "$fresh_graphql/": "https://deno.land/x/fresh_graphql/",
"preact": "https://esm.sh/preact",
"preact/": "https://esm.sh/preact/",
"preact-render-to-string": "https://esm.sh/*preact-render-to-string",
"twind": "https://esm.sh/twind",
"twind/": "https://esm.sh/twind/"
}
}2. deno.json
{
"tasks": {
- "start": "deno run -A --watch=static/,routes/ dev.ts"
+ "start": "deno run -A --watch=static/,routes/,graphql/ dev.ts"
}
}3. dev.ts
- #!/usr/bin/env -S deno run -A --watch=static/,routes/
+ #!/usr/bin/env -S deno run -A --watch=static/,routes/,graphql/
import "https://deno.land/x/dotenv/load.ts";
import dev from "$fresh/dev.ts";
+ import { dev as graphqlDev } from "$fresh_graphql/mod.ts";
+ await graphqlDev(import.meta.url);
await dev(import.meta.url, "./main.ts");Usage
Entrypoint
Any data handler routes would work, the example below uses /graphql as a
convension.
// routes/graphql.ts
import type { HandlerContext } from "$fresh/server.ts";
import { createServer } from "@graphql-yoga/common";
import { fromManifest } from "$fresh_graphql/schema.ts";
import manifest from "../fresh_graphql.gen.ts";
const schema = fromManifest(manifest);
const yoga = createServer<HandlerContext>({
logging: true,
maskedErrors: false,
schema,
});
export const handler = async (req: Request, ctx: HandlerContext) => {
return await yoga.handleRequest(req, ctx);
};@graphql-yoga/commonis chosen for itās simplicity, you may use any GraphQL serveres compatible with@graphql-tools/schema.fresh_graphql.gen.tsThis is the manifest file generated whenever you make changes to source codes in the./graphqldirectory.
Queries and Mutations
The example below follows the naming convension and use mod.ts, but you may
name your TypeScript and/or JavaScript files anyway you like.
// ./graphql/Query/test/mod.ts
export const schema = `
extend type Query {
foo: String!
}
`;
export const resolver = () => "Hello World!";Schema level types, Query, Mutation and Subscription, will be
automatically created when such a corresponding extension statement is found.
Resolver object will be wrapped according to the directory structure, i.e.
{ Query: { foo: resolver } }. To override this behavior, export an object
instead.
export const resolver = {
Query: {
bar: () => "Hello world!";
}
};Subscriptions
// graphql/Subscription/countdown/mod.ts
export const schema = `
extend type Subscription {
countdown(from: Int = 0): Int!
}
`;
export const resolver = async function* (_, { from }) {
while (from-- > 0) {
await new Promise((resolve) => setTimeout(resolve, 1000));
yield { countdown: from };
}
};Sponsorship
If you think I did a good job or want to see a feature happening, a coffee would do.