Home

Awesome

<h1 align="center"> <br> <img width="360" height="" src="https://cdn.rawgit.com/khaosdoctor/gotql/main/media/gotql.svg" alt="GotQL"> <br> <br> <br> </h1>

Write GraphQL queries as objects instead of strings

<h1 align="center"> <a href="https://opencollective.com/gotql" alt="Financial Contributors on Open Collective"> <img src="https://opencollective.com/gotql/all/badge.svg?label=financial+contributors" /> </a> <a href="https://github.com/khaosdoctor/gotql/actions?query=workflow%3A%22Build+and+Publish%22"> <img src="https://github.com/khaosdoctor/gotql/workflows/Build%20and%20Publish/badge.svg" /> </a> <a href="https://standardjs.com"> <img src= "https://img.shields.io/badge/code_style-standard-brightgreen.svg" alt="JavaScript Style Guide"> </a> </h1>

This is a better implementation of the GraphQL query API via NodeJS, created as a wrapper of Got. It works like a transpiler, with a built in HTTPRequest Client (Got), allowing you to write your GraphQL queries as Javascript Objects instead of strings.

Built because manipulating strings is a real pain.

Table of Contents

<!-- TOC --> <!-- /TOC -->

Install

$ npm install gotql

Or

$ yarn install gotql

Basic Usage

const gotQl = require('gotql')

const query = {
  operation: {
    name: 'users',
    fields: ['name', 'age', 'id']
  }
}

const options = {
  headers: {
    "Authorization": "Bearer <token>"
  },
  debug: false,
  useHttp2: false
}

gotQL.query('mygraphqlendpoint.com.br/api', query, options)
  .then(response => console.log(response.data))
  .catch(console.error)

What is it?

GotQL is a better interface for GraphQL queries. It provides a way for developers to run queries using JSON instead of strings. Which is a way more usable data format than the string itself.

See more on: https://hasura.io/blog/fluent-graphql-clients-how-to-write-queries-like-a-boss/

Motivation

Manipulating strings is very smelly, even on dynamically typed languages. So, in order to avoid things such as this:

Which can be translated to something waay more readable in a JSON format like this:

const mutation = {
  operation: {
    name: 'addLog',
    args: {
      logType: literal`status_change`, // Enum Value
      fromState: variables.fromState,
      toState: variables.toState,
      idUser: variables.idUser,
      idCampaign: variables.idCampaign,
      owner: {
        ownerType: variables.ownerType,
        username: variables.username,
        picture: variables.picture,
        name: variables.name,
        id: variables.id
      }
    },
    fields: [ 'uuid' ]
  }
}

This is why GotQL was created.

API

gotQl.query(graphQLEndpoint, query, [options])

GraphQLEndpoint

query

options

See option object for more information.


gotQl.mutation(graphQLEndpoint, query, [options])

GraphQLEndpoint

query

options

See option object for more information.


gotQl.parser(query, type)

query

type

Option Object

Both gotql.query and gotql.mutation accept an optional user option object with the following API:

Note: GotQL uses debug internally as default debugger, so you can set debug levels by setting the DEBUG environment variable. These are the current levels:

Returns

All methods return a string like this:

const response = 'query { test { name args } }'

The JSON query format

The JSON format gotQL uses is a simple and intuitive description based on the anatomy of a GraphQL query blog post.

This is a generic model of a JSONLike query:

const query = {
  name?: string,
  operation: {
    name: string,
    alias?: string,
    args?: { [argName: string]: any } | {
      [argName: string]: {
        value: string,
        escape: boolean
      }
    },
    fields: (string | {
      [fieldName: string]: [{
        args?: { [argName: string]: any } | {
          [argName: string]: {
            value: string,
            escape: boolean
          }
        },
        fields?: (string | { [fieldName: string]: [any] })[]
      }]
    })[]
  },
  variables?: {
    [varName: string]: {
      type: string,
      value: string
    }
  }
}

Description

Examples

Simple query

const query = {
  operation: {
    name: 'users',
    fields: ['name', 'age']
  }
}

Outputs:

query { users { name age } }

Named query

const query = {
  name: 'myQuery',
  operation: {
    name: 'users',
    fields: ['name', 'age']
  }
}

Outputs:

query myQuery { users { name age } }

Query with simple args

const query = {
  operation: {
    name: 'users',
    args: {
      name: 'Joe'
    },
    fields: ['name', 'age']
  }
}

Outputs:

query { users(name: "Joe") { name age } }

Query with variables

const query = {
  variables: {
    name: {
      type: 'string!',
      value: 'Joe'
    }
  },
  operation: {
    name: 'users',
    args: {
      name: '$name'
    },
    fields: ['name', 'age']
  }
}

Outputs:

query ($name: string!) { users(name: $name) { name age } }

Variables are sent on a separate object to graphQL.

{
  "variables": { "name": "Joe" }
}

Nested fields

const query = {
  operation: {
    name: 'users',
    fields: [
      'name',
      'age',
      {
        friends: {
          fields: ['name', 'age']
        }
      }
    ]
  }
}

Outputs:

query { users { name age friends { name age } } }

Recursive fields can go forever.

Enum and literal args

Enum or literal values should not be escaped, to do that, GotQL has a helper called literal which can be used to tell the query that value will not be escaped:

const { literal } = require('gotql')

const query = {
  operation: {
    name: 'users',
    args: {
      type: literal`internal`
    },
    fields: ['name', 'age']
  }
}

The code above outputs:

query { users(type: internal) { name age } }

The literal helper is just a shorthand to the old-style {value: string, escape: boolean} object like below:

const query = {
  operation: {
    name: 'users',
    args: {
      type: {
        value: 'internal',
        escape: false
      }
    },
    fields: ['name', 'age']
  }
}

If literal is omitted, or if escape is set to true, the output would be:

query { users(type: "internal") { name age } }

Note: Variables such as described here will not be recognized. If the arg object is not an [argName]: value, variables will not pass through the definition check (GotQL warns if a variable is not declared but used on operation).

Contributing to this project

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Hey! If you want to contribute, please read the contributing guidelines :smile:

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute]. <a href="https://github.com/khaosdoctor/gotql/graphs/contributors"><img src="https://opencollective.com/gotql/contributors.svg?width=890&button=false" /></a>

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

<a href="https://opencollective.com/gotql"><img src="https://opencollective.com/gotql/individuals.svg?width=890"></a>

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

<a href="https://opencollective.com/gotql/organization/0/website"><img src="https://opencollective.com/gotql/organization/0/avatar.svg"></a> <a href="https://opencollective.com/gotql/organization/1/website"><img src="https://opencollective.com/gotql/organization/1/avatar.svg"></a> <a href="https://opencollective.com/gotql/organization/2/website"><img src="https://opencollective.com/gotql/organization/2/avatar.svg"></a> <a href="https://opencollective.com/gotql/organization/3/website"><img src="https://opencollective.com/gotql/organization/3/avatar.svg"></a> <a href="https://opencollective.com/gotql/organization/4/website"><img src="https://opencollective.com/gotql/organization/4/avatar.svg"></a> <a href="https://opencollective.com/gotql/organization/5/website"><img src="https://opencollective.com/gotql/organization/5/avatar.svg"></a> <a href="https://opencollective.com/gotql/organization/6/website"><img src="https://opencollective.com/gotql/organization/6/avatar.svg"></a> <a href="https://opencollective.com/gotql/organization/7/website"><img src="https://opencollective.com/gotql/organization/7/avatar.svg"></a> <a href="https://opencollective.com/gotql/organization/8/website"><img src="https://opencollective.com/gotql/organization/8/avatar.svg"></a> <a href="https://opencollective.com/gotql/organization/9/website"><img src="https://opencollective.com/gotql/organization/9/avatar.svg"></a>