Skip to content

aaronwlee/oak-graphql

Repository files navigation

Read Me

Hello, it's Aaron. Firstly, I'd like to say thanks for using and loving oak-graphql.

Unfortunately, it is nearly impossible to maintain oak-graphql. because I'm currently serving in the military. It means oak-graphql. is no longer supported by the author at least until 2022 Nov.

Thus, I need some help! If someone wants to maintain it, please don't hesitate to give me an email. I want someone can have permission who update and push it to deno.land/x.

I hope y'all are doing well in this bad situation.

Regards
Aaron Wooseok Lee
18-July-2021
aaronwoolee95@gmail.com

Oak-GraphQL

nest badge

A simple graphql middleware for oak deno framework.

alt text

! Make sure your playground endpoint indicates same as your URL http://localhost:8080/graphql

alt text

Simple run

deno run --allow-net --unstable index.ts

Simple example index.ts

import { Application, Router } from "https://deno.land/x/oak@v10.0.0/mod.ts";
import { applyGraphQL, gql, GQLError } from "https://deno.land/x/oak_graphql/mod.ts";

const app = new Application();
// Logger
app.use(async (ctx, next) => {
  await next();
  const rt = ctx.response.headers.get("X-Response-Time");
  console.log(`${ctx.request.method} ${ctx.request.url} - ${rt}`);
});

// Timing
app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.response.headers.set("X-Response-Time", `${ms}ms`);
});



const types = gql`
type User {
  firstName: String
  lastName: String
}

input UserInput {
  firstName: String
  lastName: String
}

type ResolveType {
  done: Boolean
}

type Query {
  getUser(id: String): User 
}

type Mutation {
  setUser(input: UserInput!): ResolveType!
}
`;

const resolvers = {
  Query: {
    getUser: (parent: any, { id }: any, context: any, info: any) => {
      console.log("id", id, context);
      if(context.user === "Aaron") {
        throw new GQLError({ type: "auth error in context" })
      }
      return {
        firstName: "wooseok",
        lastName: "lee",
      };
    },
  },
  Mutation: {
    setUser: (parent: any, { input: { firstName, lastName } }: any, context: any, info: any) => {
      console.log("input:", firstName, lastName);
      return {
        done: true,
      };
    },
  },
};

const GraphQLService = await applyGraphQL<Router>({
  Router,
  typeDefs: types,
  resolvers: resolvers,
  context: (ctx) => {
  	// this line is for passing a user context for the auth
    return { user: "Aaron" };
  }
})


app.use(GraphQLService.routes(), GraphQLService.allowedMethods());

console.log("Server start at http://localhost:8080");
await app.listen({ port: 8080 });

TODO

  • Add cache
  • Enable the upload
  • Enable the JSON scalar

Method

gql

GraphQL-tag Parsing GraphQL queries

  • gql A JavaScript template literal tag that parses GraphQL query strings into the standard GraphQL AST.

GQLError

An error handler

Example

throw new GQLError("string");
or
throw new GQLError({type: "General error", detail: "somthing critical!"});

applyGraphQL

A Generator which based Attain Router class creates some middlewares for supporting the GraphQL.

Options

  • Router: oak Router module
    Due to the version incompatible issue mentioned by (avalero)[https://github.com/avalero], I've decoupled the Router. Thanks :)
  • path?: string
    A target path that handles the GraphQL post request (*optional: default as /graphql)
  • typeDefs: any
    generated type tags by the gql
  • resolvers: any
    An object that handles the queries and mutations
const resolvers = {
  Query: {
    getUser: (parent: any, {id}: any, context: any, info: any) => {
      // ...query handling function here
    },
  },
  Mutation: {
    addUser: (parent: any, {firstName, lastName}: any, context: any, info: any) => {
      // ...add user codes here
    },
  }
}

The resolvers will be received these four parameters

  • parent: The return value of the resolver for this field's parent
  • args: An object that contains all GraphQL arguments provided for this field.
  • context: An object shared across all resolvers that are executing for a particular operation.
  • info: Contains information about the operation's execution state, including the field name, the path to the field from the root, and more.
  • context?: (ctx) => any
    Send any objects to each resolver (*optional)
  • usePlayground?: boolean;
    enable the playground at get method (*optional: default as true)