v0.3.0
GraphQL server for Deno Fresh
Attributes
Includes Deno configuration
Repository
Current version released
2 years ago
Dependencies
deno.land/x
skypack.dev
@graphql-tools/schema@graphql-tools/utils
std
fresh_graphql
GraphQL development for Deno Fresh.
Live Demo
graphql-yoga
apollo-server
(soon™)
fresh_graphql
?
Why - Familiar developer experience with
fresh
projects. deno deploy
has no dynamic imports.tRPC
doesn’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:
import_map.json
1. 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/"
}
}
deno.json
2. {
"tasks": {
- "start": "deno run -A --watch=static/,routes/ dev.ts"
+ "start": "deno run -A --watch=static/,routes/,graphql/ dev.ts"
}
}
dev.ts
3. - #!/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 yoga = createServer<HandlerContext>({
logging: true,
maskedErrors: false,
schema: fromManifest(manifest),
});
export const handler = async (req: Request, ctx: HandlerContext) => {
return await yoga.handleRequest(req, ctx);
};
@graphql-yoga/common
is chosen for it’s simplicity, you may use any GraphQL serveres compatible with@graphql-tools/schema
.fresh_graphql.gen.ts
This is the manifest file generated whenever you make changes to source codes in the./graphql
directory.
Queries and Mutations
// ./graphql/Query/joke.ts
export const schema = /* GraphQL */ `
extend type Query {
joke: String!
}
`;
// Jokes courtesy of https://punsandoneliners.com/randomness/programmer-jokes/
const JOKES = [
"Why do Java developers often wear glasses? They can't C#.",
"A SQL query walks into a bar, goes up to two tables and says “can I join you?”",
"Wasn't hard to crack Forrest Gump's password. 1forrest1.",
"I love pressing the F5 key. It's refreshing.",
"Called IT support and a chap from Australia came to fix my network connection. I asked “Do you come from a LAN down under?”",
"There are 10 types of people in the world. Those who understand binary and those who don't.",
"Why are assembly programmers often wet? They work below C level.",
"My favourite computer based band is the Black IPs.",
"What programme do you use to predict the music tastes of former US presidential candidates? An Al Gore Rhythm.",
"An SEO expert walked into a bar, pub, inn, tavern, hostelry, public house.",
];
export const resolver = () => JOKES[Math.floor(Math.random() * JOKES.length)];
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: { joke: resolver } }
. To override this behavior, export an object
instead.
export const resolver = {
Query: {
foo: () => "bar";
}
};
Subscriptions
// ./graphql/Subscription/countdown.ts
export const schema = /* GraphQL */ `
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.