Skip to content
Toolkit for generating complex GraphQL Schemas on Node.js
JavaScript TypeScript
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vscode fix(TypeMapper): create proper GraphQLDirective args' types from SDL May 4, 2019
docs Update file-uploads.md May 23, 2019
flow-typed/npm fix: update flow till 0.100.0 and other dependencies Jun 4, 2019
src docs: add Field Args methods block for ObjectTypeComposer Jul 23, 2019
.babelrc build: drop node 6 support Apr 28, 2019
.eslintignore feat: add mjs build (es6 modules) Jun 26, 2018
.eslintrc style: common pretterrc file Apr 4, 2019
.flowconfig feat: add mjs build (es6 modules) Jun 26, 2018
.gitignore feat: add mjs build (es6 modules) Jun 26, 2018
.markdownlint.json chore: update dependencies Apr 28, 2019
.npmignore chore(typescript): move type defs from types/ to src/ Sep 15, 2017
.prettierignore docs: Activating Open Collective 🍻(#118) May 16, 2018
.prettierrc style: common pretterrc file Apr 4, 2019
.travis.yml ci: change node v8 to v12 on travis tests Jul 23, 2019
AUTHORS Initial commit Jun 7, 2016
CHANGELOG.md docs(Changelog): See in the GitHub releases tab Jan 25, 2017
LICENSE.md Initial commit Jun 7, 2016
README.md chore: update dependencies Apr 28, 2019
jest.config.js refactor: all TypeComposers for creation now required a second argume… Mar 15, 2019
package.json chore: update dependencies Jul 23, 2019
tsconfig.json feat: add UnionTypeComposer helper Jan 31, 2019
tslint.json chore: update dependencies Apr 28, 2019
yarn.lock chore: update dependencies Jul 23, 2019

README.md

graphql-compose

codecov coverage Travis npm Commitizen friendly TypeScript compatible FlowType compatible Backers on Open Collective Sponsors on Open Collective

GraphQL – is a query language for APIs. graphql-js is the reference implementation of GraphQL for nodejs which introduce GraphQL type system for describing schema (definition over configuration) and executes queries on the server side. express-graphql is a HTTP server which gets request data, passes it to graphql-js and returned result passes to response.

graphql-compose – the imperative tool which worked on top of graphql-js. It provides some methods for creating types and GraphQL Models (so I call types with a list of common resolvers) for further building of complex relations in your schema.

  • provides methods for editing GraphQL output/input types (add/remove fields/args/interfaces)
  • introduces Resolvers – the named graphql fieldConfigs, which can be used for finding, updating, removing records
  • provides an easy way for creating relations between types via Resolvers
  • provides converter from OutputType to InputType
  • provides projection parser from AST
  • provides GraphQL schema language for defining simple types
  • adds additional types Date, Json

graphql-compose-[plugin] – is a declarative generators/plugins that build on top of graphql-compose, which take some ORMs, schema definitions and creates GraphQL Models from them or modify existed GraphQL Types.

Type generator plugins:

Utility plugins:

Documentation

graphql-compose.github.io

Live Demos

Examples

Please follow Quick Start Guide for the complete example.

Here is just a demo of ambiguity ways of types definitions:

import { schemaComposer} from 'graphql-compose';

// You may use SDL format for type definition
const CityTC = schemaComposer.createObjectTC(`
  type City {
    code: String!
    name: String!
    population: Number
    countryCode: String
    tz: String
  }
`);

// Define type via Config object
const CountryTC = schemaComposer.createObjectTC({
  name: 'Country',
  fields: {
    title: 'String',
    geo: `type LonLat { lon: Float, lat: Float }`,
    hoisting: {
      type: () => AnotherTC,
      description: `
        You may wrap type in thunk for solving
        hoisting problems when two types cross reference
        each other.
      `,
    }
  }
});

// Or via declarative methods define some additional fields
CityTC.addFields({
  country: CountryTC, // some another Type
  ucName: { // standard GraphQL like field definition
    type: GraphQLString,
    resolve: (source) => source.name.toUpperCase(),
  },
  currentLocalTime: { // extended GraphQL Compose field definition
    type: 'Date',
    resolve: (source) => moment().tz(source.tz).format(),
    projection: { tz: true }, // load `tz` from database, when requested only `localTime` field
  },
  counter: 'Int', // shortening for only type definition for field
  complex: `type ComplexType {
    subField1: String
    subField2: Float
    subField3: Boolean
    subField4: ID
    subField5: JSON
    subField6: Date
  }`,
  list0: {
    type: '[String]',
    description: 'Array of strings',
  },
  list1: '[String]',
  list2: ['String'],
  list3: [new GraphQLOutputType(...)],
  list4: [`type Complex2Type { f1: Float, f2: Int }`],
});

// Add resolver method
CityTC.addResolver({
  kind: 'query',
  name: 'findMany',
  args: {
    filter: `input CityFilterInput {
      code: String!
    }`,
    limit: {
      type: 'Int',
      defaultValue: 20,
    },
    skip: 'Int',
    // ... other args if needed
  },
  type: [CityTC], // array of cities
  resolve: async ({ args, context }) => {
    return context.someCityDB
      .findMany(args.filter)
      .limit(args.limit)
      .skip(args.skip);
  },
});

// Remove `tz` field from schema
CityTC.removeField('tz');

// Add description to field
CityTC.extendField('name', {
  description: 'City name',
});

schemaComposer.Query.addFields({
  cities: CityTC.getResolver('findMany'),
  currentTime: {
    type: 'Date',
    resolve: () => Date.now(),
  },
});

schemaComposer.Mutation.addFields({
  createCity: CityTC.getResolver('createOne'),
  updateCity: CityTC.getResolver('updateById'),
  ...adminAccess({
    removeCity: CityTC.getResolver('removeById'),
  }),
});

function adminAccess(resolvers) {
  Object.keys(resolvers).forEach(k => {
    resolvers[k] = resolvers[k].wrapResolve(next => rp => {
      // rp = resolveParams = { source, args, context, info }
      if (!rp.context.isAdmin) {
        throw new Error('You should be admin, to have access to this action.');
      }
      return next(rp);
    });
  });
  return resolvers;
}

// construct schema which can be passed to express-graphql, apollo-server or graphql-yoga
export const schema = schemaComposer.buildSchema();

Contributors

This project exists thanks to all the people who contribute.

Backers

Thank you to all our backers! 🙏 [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

License

MIT

You can’t perform that action at this time.