Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

This is a plugin for graphql-compose, which generates GraphQLTypes from any JSON.

License

NotificationsYou must be signed in to change notification settings

graphql-compose/graphql-compose-json

Repository files navigation

travis buildcodecov coveragenpmtrendsCommitizen friendly

This is a plugin forgraphql-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 aLive demo (source coderepo) which shows how to build an API uponSWAPI usinggraphql-compose-json.

Installation

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

Modulesgraphql,graphql-compose, are located inpeerDependencies, 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 objectrestApiResponse which you can pass tographql-compose-json along with desired type name as your first argument and it will automatically generate a composed GraphQL typePersonTC.

// person.jsimport{composeWithJson,composeInputWithJson}from'graphql-compose-json';constrestApiResponse={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/',],};exportconstPersonTC=composeWithJson('Person',restApiResponse);exportconstPersonGraphQLType=PersonTC.getType();// GraphQLObjectTypeexportconstPersonITC=composeInputWithJson('PersonInput',restApiResponse);exportconstPersonGraphQLInput=PersonITC.getType();// GraphQLInputObjectType

Customization

You can write custom field configs directly to a field of your API response object via function (seemass andstarships_count field):

import{composeWithJson}from'graphql-compose-json';constrestApiResponse={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 JSON numbers coerced to Float, here we set up Intstarships_count:()=>({// more granular field config with resolve functiontype:'Int',resolve:source=>source.starships.length,}),};exportconstCustomPersonTC=composeWithJson('CustomPerson',restApiResponse);exportconstCustomPersonGraphQLType=CustomPersonTC.getType();

Will be produced following GraphQL Type from upper shape:

constCustomPersonGraphQLType=newGraphQLObjectType({name:'CustomPerson',fields:()=>{name:{type:GraphQLString,},birth_year:{type:GraphQLString,},starships:{type:newGraphQLList(GraphQLString),},mass:{type:GraphQLInt,},starships_count:{type:GraphQLInt,resolve:source=>source.starships.length,},},});

Schema building

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

// schema.jsimport{GraphQLSchema,GraphQLObjectType,GraphQLNonNull,GraphQLInt}from'graphql';importfetchfrom'node-fetch';import{PersonTC}from'./person';constschema=newGraphQLSchema({query:newGraphQLObjectType({name:'Query',fields:{person:{type:PersonTC.getType(),// get GraphQL type from PersonTCargs:{id:{type:newGraphQLNonNull(GraphQLInt),}},resolve:(_,args)=>fetch(`https://swapi.co/api/people/${args.id}/`).then(r=>r.json()),},},}),});

Or do the same viagraphql-compose:

import{SchemaComposer}from'graphql-compose';constschemaComposer=newSchemaComposer();constPersonTC=composeWithJson('CustomPerson',restApiResponse,{ schemaComposer});schemaComposer.Query.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()),},}constschema=schemaComposer.buildSchema();// returns GraphQLSchema

Building schema asynchronously

To build the schema at the runtime, you should rewrite theSchema.js and insert there an async function which will return a promise:

exportconstbuildAsyncSchema=async():Promise<GraphQLSchema>=>{consturl=`https://swapi.co/api/people/1`;constdata=awaitfetch(url);constjsonData=awaitdata.json();constPeopleTC=composeWithJson('People',jsonData);schemaComposer.Query.addFields({person:{type:PeopleTC,args:{id:'Int!',},resolve:(_,args)=>{returnfetch(`https://swapi.co/api/people/${args.id}/`).then(r=>r.json());},},});constschema=schemaComposer.buildSchema();returnschema;};

So, you can just import this function and tell to theexpress-graphql that we are passing a promise:

importexpressfrom'express';importgraphqlHTTPfrom'express-graphql';import{buildAsyncSchema}from'./Schema';constPORT=4000;constapp=express();constpromiseSchema=buildAsyncSchema();app.use('/graphql',graphqlHTTP(asyncreq=>({schema:awaitpromiseSchema,graphiql:true,context:req,})));

Further customization withgraphql-compose

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

constrestApiResponse={name:'Anakin Skywalker',starships:()=>StarshipTC.getResolver('findByUrlList')// get some standard resolver.wrapResolve(next=>rp=>{// wrap with additional logicconststarshipsUrls=rp.source.starships;rp.args.urls=starshipsUrls;// populate `urls` arg from sourcereturnnext(rp);// call standard resolver}).removeArg('urls'),// remove `urls` args from resolver and schema};}constPersonTC=composeWithJson('Person',restApiResponse);

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

If you want to specify new fields of your type, simply use theaddFields method ofgraphql-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 useaddRelation method ofgraphql-compose:

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

graphql-compose provides a vast variety of methods forfields andresolvers (aka field configs in vanillaGraphQL) management ofGraphQL types. To learn more visitgraphql-compose repo.

License

MIT

About

This is a plugin for graphql-compose, which generates GraphQLTypes from any JSON.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

No packages published

Contributors6


[8]ページ先頭

©2009-2025 Movatter.jp