Show More
Commit Commit message Age Author Refs
r14:e43626d887d2
Updated README
0
r13:c0a3f8176b69
Updated deps and linted
0
r12:49e17ccc4caa
This should fix the "invalid character in header content" error
0
r11:c30539b76ffd
Removed invalid character from header content
0
r10:0b65c0c1d939
Updated README
0
r9:a63264385d24
Updated deps and minor refactor
0
r8:4912b2097257
1.4.1
ポール ウェッブ
0
r7:570004e9e4cf
README update
ポール ウェッブ
0
r6:5df944e9a50c
README update
ポール ウェッブ
0
r5:ca2b2678da39
README update
ポール ウェッブ
0
< 1 2 >

@inc/gotql

Write GraphQL queries as objects instead of strings

Forked from khaosdoctor/gotql because I did not feel like waiting nearly four months for my PR to be accepted and I had things to do.

Vulnerabilities in this package

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

Install

$ npm i @inc/gotql

Basic Usage

import gotQL from "gotql";

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

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

gotQL.query("mygraphqlendpoint.com.br/api", query, options)
  .then(response => console.log(response.data))
  .catch(error => console.error(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.

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 more readable in a JSON format like this:

const mutation = {
  operation: {
    name: "addLog",
    args: {
      fromState: variables.fromState,
      idCampaign: variables.idCampaign,
      idUser: variables.idUser,
      logType: {
        escape: false,
        value: "status_change"
      }, // Enum Value
      owner: {
        id: variables.id,
        name: variables.name,
        ownerType: variables.ownerType,
        picture: variables.picture,
        username: variables.username
      },
      toState: variables.toState
    },
    fields: [
      "uuid"
    ]
  }
};

This is why GotQL was created.

API

gotQL.query(graphQLEndpoint, query, [options]);
  • Description: Performs a graphQL query

GraphQLEndpoint

  • Type: string
  • Description: The GraphQL endpoint to query on

query

options

  • Type: object
  • Description: The option object with the following properties.
  • debug: Activates debug logging
    • Type: boolean
  • errorStatusCode: Default HTTP status code to be returned on error
    • Type: number
  • headers: Additional headers to be sent
    • Type: object, in the form of [headerName: string]: headerValue: string

gotQL.mutation(graphQLEndpoint, query, [options]);
  • Description: Performs a graphQL mutation

GraphQLEndpoint

  • Type: string
  • Description: The GraphQL endpoint to query on

query

options

  • Type: object
  • Description: The option object with the following properties.
  • debug: Activates debug logging
    • Type: boolean
  • errorStatusCode: Default HTTP status code to be returned on error
    • Type: number
  • headers: Additional headers to be sent
    • Type: object, in the form of [headerName: string]: headerValue: string

gotQL.parser(query, type);
  • Description: Parses a JSON-Like query and returns the query"s string

query

type

  • Type: string
  • Description: Must be either "query" or "mutation"

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]: {
        escape: boolean;
        value: string;
      };
    };
    fields: (string | {
      [fieldName: string]: [{
        fields?: (string | {
          [fieldName: string]: [any];
        })[];
      }];
    })[];
  };
  variables?: {
    [varName: string]: {
      type: string;
      value: string;
    };
  };
};

Description

  • Query:
  • Type: object
  • Description: The full query object
  • Properties:
    • name: [optional]: Query name
    • Type: string
    • variables: [optional] Query variable declaration
    • Type: object with signature like [varName: string]: { type: string, value: string }
    • Properties:
      • varName: Variable name
      • Type: string
      • type: Variable type. Can be a GraphQL definition of type (i.e: string!)
      • Type: string
      • value: Variable value
      • Type: any
    • operation: The query operation (action that will be executed)
    • Type: object
    • Properties:
      • name: The operation name
      • Type: string
      • alias: [optional] An alias to give the operation
      • Type: string
      • args: [optional] The operation args
      • Type: [argName: string]: any or a detailed arg object
        • Simple args: An object where the key is the argument name and its value. Accepts variables in the format of argName: "$value"
        • Example: args { name: "myName" }
        • Detailed args: An object with two properties. This will give more control over escaping (mostly to use enums). Argument name should be the key
        • Type: object
        • Properties:
          • value: The argument value
          • Type: any
          • escape: Whether the argument should be escaped or not (escaped means surrounded with double quotes "argValue")
          • Type: boolean
        • Examples: args: { status: { value: "an_enum", escape: false } } should output operation (status: an_enum)...
      • fields: The field list to get back from the operation
      • Type: An array of object (to use nested fields) or string, or both.
      • Properties (for nested fields):
        • Type: object where the field name is the key
        • fields: Recursive definition, accepts another array just like the fields above.

Examples

Simple query

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

Outputs:

query { users { name age }}

Named query

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

Outputs:

query myQuery { users { name age }}

Query with simple args

const query = {
  operation: {
    name: "user",
    args: {
      name: "T'Challa"
    },
    fields: [
      "age",
      "name"
    ]
  }
};

Outputs:

query { user(name: "T'Challa") { name age }}

Query with variables

const query = {
  operation: {
    name: "user",
    args: {
      name: "$name"
    },
    fields: [
      "age",
      "name"
    ]
  },
  variables: {
    name: {
      type: "string!",
      value: "T'Challa"
    }
  }
};

Outputs:

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

Variables are sent on a separate object to graphQL.

{
  "variables": {
    "name": "T'Challa"
  }
}

Nested fields

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

Outputs:

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

Recursive fields can go forever.

Enum args

const query = {
  operation: {
    name: "user",
    args: {
      type: {
        escape: false,
        value: "internal"
      }
    },
    fields: [
      "age",
      "name"
    ]
  }
};

Outputs:

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

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).