Git Product home page Git Product logo

graphql-compose-json's Introduction

graphql-compose-json

travis build codecov coverage npm Commitizen friendly Greenkeeper badge

This is a plugin for graphql-compose, which generates GraphQLTypes from REST response or any JSON. It takes fields from object, determines their types and construct GraphQLObjectType with same shape.

Demo

We have a Live demo (source code repo) which shows how to build an API upon SWAPI using graphql-compose-json.

Installation

npm install graphql graphql-compose graphql-compose-json --save

Modules graphql, graphql-compose, are located in peerDependencies, so they should be installed explicitly in your app. They have global objects and should not have ability to be installed as submodule.

Example

You have a sample response object restApiResponse which you can pass to graphql-compose-json along with desired type name as your first argument and it will automatically generate a composed GraphQL type PersonTC.

// person.js

import composeWithJson from 'graphql-compose-json';

const restApiResponse = {
  name: 'Anakin Skywalker',
  birth_year: '41.9BBY',
  gender: 'male',
  mass: 77,
  homeworld: 'https://swapi.co/api/planets/1/',
  films: [
    'https://swapi.co/api/films/5/',
    'https://swapi.co/api/films/4/',
    'https://swapi.co/api/films/6/',
  ],
  species: ['https://swapi.co/api/species/1/'],
  starships: [
    'https://swapi.co/api/starships/59/',
    'https://swapi.co/api/starships/65/',
    'https://swapi.co/api/starships/39/',
  ],
};

export const PersonTC = composeWithJson('Person', restApiResponse);
export const PersonGraphQLType = PersonTC.getType();

Customization

You can write custom field configs directly to a field of your API response object via function (see mass and starships_count field):

const restApiResponse = {
  name: 'Anakin Skywalker',
  birth_year: '41.9BBY',
  starships: [
    'https://swapi.co/api/starships/59/',
    'https://swapi.co/api/starships/65/',
    'https://swapi.co/api/starships/39/',
  ],
  mass: () => 'Int', // by default numbers coerced to Float, here we set up Int
  starships_count: () => ({ // more granular field config with resolve function
    type: 'Int',
    resolve: source => source.starships.length,
  }),
};

Schema building

Now when you have your type built, you may specify the schema and data fetching method:

// schema.js
import { GraphQLSchema, GraphQLObjectType, GraphQLNonNull, GraphQLInt } from 'graphql';
import fetch from 'node-fetch';
import { PersonTC } from './person';

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'Query',
    fields: {
      person: {
        type: PersonTC.getType(), // get GraphQL type from PersonTC
        args: {
          id: {
            type: new GraphQLNonNull(GraphQLInt),
          }
        },
        resolve: (_, args) =>
          fetch(`https://swapi.co/api/people/${args.id}/`).then(r => r.json()),
      },
    },
  }),
});

Or do the same via graphql-compose:

import { GQC } from 'graphql-compose';

GQC.rootQuery().addFields({
  person: {
    type: PersonTC,
    args: {
      id: `Int!`, // equals to `new GraphQLNonNull(GraphQLInt)`
    },
    resolve: (_, args) =>
      fetch(`https://swapi.co/api/people/${args.id}/`).then(r => r.json()),
  },
}

const schema = GQC.buildSchema(); // returns GraphQLSchema

Further customization with graphql-compose

Moreover, graphql-compose allows you to pass pre-defined resolvers of other types to the response object and customize them:

const restApiResponse = {
  name: 'Anakin Skywalker',
  starships: () =>
    PeopleTC.getResolver('findByUrlList') // get some standard resolver
      .wrapResolve(next => rp => { // wrap with additional logic
        const starshipsUrls = rp.source.starships;
        rp.args.urls = starshipsUrls; // populate `urls` arg from source
        return next(rp); // call standard resolver
      })
      .removeArg('urls'), // remove `urls` args from resolver and schema
  };
}

const PersonTC = composeWithJson('Person', restApiResponse);

In case you need to separate custom field definition from your response object there are graphql-compose methods made for this purpose.

If you want to specify new fields of your type, simply use the addFields method of graphql-compose:

PersonTC.addFields({
  vehicles_count: {
    type: 'Int!', // equals to `new GraphQLNonNull(GraphQLInt)`
    resolve: (source) => source.vehicles.length,
  },
});

When you want to create a relation with another type simply use addRelation method of graphql-compose:

PersonTC.addRelation('filmObjects', {
  resolver: () => FilmTC.getResolver('findByUrlList'),
  prepareArgs: {
    urls: source => source.films,
  },
});

graphql-compose provides a vast variety of methods for fields and resolvers (aka field configs in vanilla GraphQL) management of GraphQL types. To learn more visit graphql-compose repo.

License

MIT

graphql-compose-json's People

Contributors

borodayev avatar lyskos97 avatar nodkz avatar

Watchers

 avatar

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.