GithubHelp home page GithubHelp logo

custom-resolvers-boilerplate's Introduction

Important: Moved to hasura/graphql-engine

The contents of this repo have been moved to hasura/graphql-engine. Please create all issues and pull requests there.


GraphQL Custom Resolver Example

This is a simple example of using a custom resolver with Hasura's GraphQL API.

Motivation

Hasura GraphQL Engine provides instant GraphQL APIs over the tables and views of any Postgres database. It also comes with a fine grained access control layer that helps you restrict the data that can be consumed.

However, sometimes you might have to write custom resolvers to capture business logic that is unrelated to the database or needs to execute a custom transaction or write to the database.

In this example, we illustrate how to write custom resolvers and merge them with the Hasura GraphQL Engine. We combine Hasura GraphQL Engine's GraphQL API running at https://bazookaand.herokuapp.com/v1alpha1/graphql with the following custom resolvers:

  1. A hello query
  2. A count query (that returns a counter from another data source )
  3. A increment_counter mutation that increments the value of count.
  4. A user_average_age query that makes directly makes an SQL query to Postgres using knex.

You can use this as a boilerplate to write custom resolvers with Hasura GraphQL Engine.

Custom resolvers with Hasura GraphQL engine

Usage

  1. Enter the directory and install the required dependencies.
npm install
  1. Set appropriate environment variables for the GraphQL Engine URL, the access key to GraphQL Engine and the Postgres connection string.
export HASURA_GRAPHQL_ENGINE_URL='https://hge.herokuapp.com'
export X_HASURA_ACCESS_KEY='<access_key>'
export PG_CONNECTION_STRING='<postgres-connection-string>' #Only required for the direct SQL resolver
  1. Run the server
npm start

Deployment

You can deploy this sample boilerplate with:

  1. Heroku
  2. Now
  3. Docker

Deploy with Heroku

Press the button below to deploy with heroku:

Deploy

Deploy using Now

Run these commands to instantly deploy this boilerplate using Now.

git clone https://github.com/hasura/custom-resolvers-boilerplate
cd custom-resolvers-boilerplate
now -e \
  HASURA_GRAPHQL_ENGINE_URL='https://hge.herokuapp.com' -e \
  X_HASURA_ACCESS_KEY='<access_key>' --npm

Deploy the docker image

This project comes with a Dockerfile. You can deploy it wherever you wish.

Implementation Details

We will use Apollo's graphql-tools library to make a working GraphQL Schema out of our custom resolvers. Finally, we will merge these resolvers with the existing Hasura schema so that it can be queried under the same endpoint.

Writing type definitions

The type definitions are written in standard GraphQL format. We need the following queries in our custom logic:

type Query {
  # field hello will return "Hello World" which is a string
  hello: String,

  # field count will return an Int
  count: Int,

  # field user_average_age will return a Float
  user_average_age: Float
}

type Mutation {
  # field "increment_counter" will increment the counter and return type IncrementCounter
  increment_counter: IncrementCounter,

  # IncrementCounter simply returns the new value of the counter
  new_count: Int
}

Writing resolvers

Every resolver is a function that is executed with the following arguments in the order below:

  1. root: The root of the current field
  2. args: The arguments provided in the query
  3. context: The server context, which also consists of headers
  4. info: The AST document related to the query made

The resolvers in our case are:

const resolvers = {
  // resolvers for queries
  Query: {
    hello: (root, args, context, info) => {
      // return response
      return 'Hello world!';
    },
    count: (root, args, context, info) => {
      // return response
      return count;
    },
    user_average_age: async (root, args, context, info) => {
      // make SQL query using knex client
      const response = await knexClient('user')
        .avg('age');
      // return response
      return response[0].avg;
    }
  },

  // resolvers for mutations
  Mutation: {
    increment_counter: (root, args, context, info) => {
      // return response
      return { new_count: ++count };
    }
  }
};

Making a new schema out of these custom resolvers

Use makeExecutableSchema() function from the graphql-tools library to make a schema out of the type definitions and resolvers above.

import { makeExecutableSchema } from 'graphql-tools';

const executableCustomSchema = makeExecutableSchema({
  typeDefs,
  resolvers,
});

Merging with existing Hasura schema and serving it

Merge these custom resolvers with the Hasura GraphQL Engine by using the mergeSchemas() function from the graphql-tools library.

import { mergeSchemas } from 'graphql-tools';

const newSchema = mergeSchemas({
  schemas: [
    executableCustomSchema,
    executableHasuraSchema
  ]
});

const server = new ApolloServer({
  schema: newSchema
});

server.listen().then(({ url }) => {
  console.log(`Server running at ${url}`);
});

Check this file to see how it is done.

custom-resolvers-boilerplate's People

Contributors

coco98 avatar rikinsk avatar shahidhk avatar wawhal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

custom-resolvers-boilerplate's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.