{"id":13881026,"url":"https://github.com/graphql-compose/graphql-compose-json","last_synced_at":"2025-03-17T02:31:09.489Z","repository":{"id":26545296,"uuid":"109370994","full_name":"graphql-compose/graphql-compose-json","owner":"graphql-compose","description":"This is a plugin for graphql-compose, which generates GraphQLTypes from any JSON.","archived":false,"fork":false,"pushed_at":"2023-01-07T03:51:09.000Z","size":1797,"stargazers_count":63,"open_issues_count":13,"forks_count":10,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-30T00:00:31.136Z","etag":null,"topics":["graphql","graphql-compose","graphql-compose-plugin","rest"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/graphql-compose.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["nodkz"],"patreon":null,"open_collective":"graphql-compose","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2017-11-03T08:26:38.000Z","updated_at":"2023-08-22T19:27:26.000Z","dependencies_parsed_at":"2023-01-14T04:54:07.131Z","dependency_job_id":null,"html_url":"https://github.com/graphql-compose/graphql-compose-json","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-compose%2Fgraphql-compose-json","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-compose%2Fgraphql-compose-json/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-compose%2Fgraphql-compose-json/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-compose%2Fgraphql-compose-json/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/graphql-compose","download_url":"https://codeload.github.com/graphql-compose/graphql-compose-json/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243802938,"owners_count":20350315,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","graphql-compose","graphql-compose-plugin","rest"],"created_at":"2024-08-06T08:03:48.595Z","updated_at":"2025-03-17T02:31:09.472Z","avatar_url":"https://github.com/graphql-compose.png","language":"TypeScript","readme":"# graphql-compose-json\n\n[![travis build](https://img.shields.io/travis/graphql-compose/graphql-compose-json.svg)](https://travis-ci.org/graphql-compose/graphql-compose-json)\n[![codecov coverage](https://img.shields.io/codecov/c/github/graphql-compose/graphql-compose-json.svg)](https://codecov.io/github/graphql-compose/graphql-compose-json)\n[![npm](https://img.shields.io/npm/v/graphql-compose-json.svg)](https://www.npmjs.com/package/graphql-compose-json)\n[![trends](https://img.shields.io/npm/dt/graphql-compose-json.svg)](http://www.npmtrends.com/graphql-compose-json)\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)\n\nThis is a plugin for [graphql-compose](https://github.com/nodkz/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.\n\n## Demo\n\nWe have a [Live demo](https://graphql-compose-swapi.herokuapp.com/?query=%7B%0A%20%20person%28id%3A%201%29%20%7B%0A%20%20%20%20name%0A%20%20%20%20films%20%7B%0A%20%20%20%20%20%20title%0A%20%20%20%20%20%20release_date%0A%20%20%20%20%20%20director%0A%20%20%20%20%7D%0A%20%20%20%20homeworld%20%7B%0A%20%20%20%20%20%20name%0A%20%20%20%20%20%20climate%0A%20%20%20%20%20%20diameter%0A%20%20%20%20%7D%0A%20%20%20%20starships%20%7B%0A%20%20%20%20%20%20name%0A%20%20%20%20%20%20cost_in_credits%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A) (source code [repo](https://github.com/lyskos97/graphql-compose-swapi)) which shows how to build an API upon [SWAPI](https://swapi.co) using `graphql-compose-json`.\n\n## Installation\n\n```bash\nnpm install graphql graphql-compose graphql-compose-json --save\n```\n\nModules `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.\n\n## Example\n\nYou 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`.\n\n```js\n// person.js\n\nimport { composeWithJson, composeInputWithJson } from 'graphql-compose-json';\n\nconst restApiResponse = {\n  name: 'Anakin Skywalker',\n  birth_year: '41.9BBY',\n  gender: 'male',\n  mass: 77,\n  homeworld: 'https://swapi.co/api/planets/1/',\n  films: [\n    'https://swapi.co/api/films/5/',\n    'https://swapi.co/api/films/4/',\n    'https://swapi.co/api/films/6/',\n  ],\n  species: ['https://swapi.co/api/species/1/'],\n  starships: [\n    'https://swapi.co/api/starships/59/',\n    'https://swapi.co/api/starships/65/',\n    'https://swapi.co/api/starships/39/',\n  ],\n};\n\nexport const PersonTC = composeWithJson('Person', restApiResponse);\nexport const PersonGraphQLType = PersonTC.getType(); // GraphQLObjectType\n\nexport const PersonITC = composeInputWithJson('PersonInput', restApiResponse);\nexport const PersonGraphQLInput = PersonITC.getType(); // GraphQLInputObjectType\n```\n\n## Customization\n\nYou can write custom field configs directly to a field of your API response object via function (see `mass` and `starships_count` field):\n\n```js\nimport { composeWithJson } from 'graphql-compose-json';\n\nconst restApiResponse = {\n  name: 'Anakin Skywalker',\n  birth_year: '41.9BBY',\n  starships: [\n    'https://swapi.co/api/starships/59/',\n    'https://swapi.co/api/starships/65/',\n    'https://swapi.co/api/starships/39/',\n  ],\n  mass: () =\u003e 'Int!', // by default JSON numbers coerced to Float, here we set up Int\n  starships_count: () =\u003e ({ // more granular field config with resolve function\n    type: 'Int',\n    resolve: source =\u003e source.starships.length,\n  }),\n};\n\nexport const CustomPersonTC = composeWithJson('CustomPerson', restApiResponse);\nexport const CustomPersonGraphQLType = CustomPersonTC.getType();\n```\n\nWill be produced following GraphQL Type from upper shape:\n\n```js\nconst CustomPersonGraphQLType = new GraphQLObjectType({\n  name: 'CustomPerson',\n  fields: () =\u003e {\n    name: {\n      type: GraphQLString,\n    },\n    birth_year: {\n      type: GraphQLString,\n    },\n    starships: {\n      type: new GraphQLList(GraphQLString),\n    },\n    mass: {\n      type: GraphQLInt,\n    },\n    starships_count: {\n      type: GraphQLInt,\n      resolve: source =\u003e source.starships.length,\n    },\n  },\n});\n```\n\n## Schema building\n\nNow when you have your type built, you may specify the schema and data fetching method:\n\n```js\n// schema.js\nimport { GraphQLSchema, GraphQLObjectType, GraphQLNonNull, GraphQLInt } from 'graphql';\nimport fetch from 'node-fetch';\nimport { PersonTC } from './person';\n\nconst schema = new GraphQLSchema({\n  query: new GraphQLObjectType({\n    name: 'Query',\n    fields: {\n      person: {\n        type: PersonTC.getType(), // get GraphQL type from PersonTC\n        args: {\n          id: {\n            type: new GraphQLNonNull(GraphQLInt),\n          }\n        },\n        resolve: (_, args) =\u003e\n          fetch(`https://swapi.co/api/people/${args.id}/`).then(r =\u003e r.json()),\n      },\n    },\n  }),\n});\n```\n\nOr do the same via `graphql-compose`:\n\n```js\nimport { SchemaComposer } from 'graphql-compose';\n\nconst schemaComposer = new SchemaComposer();\nconst PersonTC = composeWithJson('CustomPerson', restApiResponse, { schemaComposer });\n\nschemaComposer.Query.addFields({\n  person: {\n    type: PersonTC,\n    args: {\n      id: `Int!`, // equals to `new GraphQLNonNull(GraphQLInt)`\n    },\n    resolve: (_, args) =\u003e\n      fetch(`https://swapi.co/api/people/${args.id}/`).then(r =\u003e r.json()),\n  },\n}\n\nconst schema = schemaComposer.buildSchema(); // returns GraphQLSchema\n```\n\n## Building schema asynchronously\n\nTo build the schema at the runtime, you should rewrite the `Schema.js` and insert there an async function which will return a promise:\n\n```js\nexport const buildAsyncSchema = async (): Promise\u003cGraphQLSchema\u003e =\u003e {\n  const url = `https://swapi.co/api/people/1`;\n  const data = await fetch(url);\n  const jsonData = await data.json();\n\n  const PeopleTC = composeWithJson('People', jsonData);\n\n  schemaComposer.Query.addFields({\n    person: {\n      type: PeopleTC,\n      args: {\n        id: 'Int!',\n      },\n      resolve: (_, args) =\u003e {\n        return fetch(`https://swapi.co/api/people/${args.id}/`).then(r =\u003e r.json());\n      },\n    },\n  });\n\n  const schema = schemaComposer.buildSchema();\n  return schema;\n};\n```\n\nSo, you can just import this function and tell to the `express-graphql` that we are passing a promise:\n\n```js\nimport express from 'express';\nimport graphqlHTTP from 'express-graphql';\nimport { buildAsyncSchema } from './Schema';\n\nconst PORT = 4000;\nconst app = express();\nconst promiseSchema = buildAsyncSchema();\n\napp.use(\n  '/graphql',\n  graphqlHTTP(async req =\u003e ({\n    schema: await promiseSchema,\n    graphiql: true,\n    context: req,\n  }))\n);\n```\n\n## Further customization with `graphql-compose`\n\nMoreover, `graphql-compose` allows you to pass pre-defined resolvers of other types to the response object and customize them:\n\n```js\nconst restApiResponse = {\n  name: 'Anakin Skywalker',\n  starships: () =\u003e\n    StarshipTC.getResolver('findByUrlList') // get some standard resolver\n      .wrapResolve(next =\u003e rp =\u003e { // wrap with additional logic\n        const starshipsUrls = rp.source.starships;\n        rp.args.urls = starshipsUrls; // populate `urls` arg from source\n        return next(rp); // call standard resolver\n      })\n      .removeArg('urls'), // remove `urls` args from resolver and schema\n  };\n}\n\nconst PersonTC = composeWithJson('Person', restApiResponse);\n```\n\nIn case you need to separate custom field definition from your response object there are `graphql-compose` methods made for this purpose.\n\nIf you want to specify new fields of your type, simply use the `addFields` method of `graphql-compose`:\n\n```js\nPersonTC.addFields({\n  vehicles_count: {\n    type: 'Int!', // equals to `new GraphQLNonNull(GraphQLInt)`\n    resolve: (source) =\u003e source.vehicles.length,\n  },\n});\n```\n\nWhen you want to create a relation with another type simply use `addRelation` method of `graphql-compose`:\n\n```js\nPersonTC.addRelation('filmObjects', {\n  resolver: () =\u003e FilmTC.getResolver('findByUrlList'),\n  prepareArgs: {\n    urls: source =\u003e source.films,\n  },\n});\n```\n\n`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](https://github.com/nodkz/graphql-compose).\n\n## License\n\n[MIT](https://github.com/graphql-compose/graphql-compose-json/blob/master/LICENSE.md)\n","funding_links":["https://github.com/sponsors/nodkz","https://opencollective.com/graphql-compose"],"categories":["📦 Legacy \u0026 Inactive Projects","TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphql-compose%2Fgraphql-compose-json","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgraphql-compose%2Fgraphql-compose-json","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphql-compose%2Fgraphql-compose-json/lists"}