
graphql-compose

graphql-compose β provides a type registry with a bunch of methods for programmatic schema construction. It allows not only to extend types but also remove fields, interfaces, args. If you want to write your graphql schema generator β graphql-compose is a good instrument for you.
- provides methods for editing GraphQL output/input types (add/remove fields/args/interfaces)
- introduces
Resolver's β the named graphql fieldConfigs, which can be used for finding, updating, removing records
- provides an easy way for creating relations between types via
Resolver's
- provides converter from
OutputType to InputType
- provides
projection parser from AST
- provides
GraphQL schema language for defining simple types
- adds additional types
Date, Json
And a little bit more
graphql-compose-[plugin] β are declarative generators/plugins built on top of graphql-compose, which take some ORMs, schema definitions and create GraphQL Models from them or modify existing GraphQL Types.
Type generators built on top graphql-compose
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';
const CityTC = schemaComposer.createObjectTC(`
type City {
code: String!
name: String!
population: Number
countryCode: String
tz: String
}
`);
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.
`,
}
}
});
CityTC.addFields({
country: CountryTC,
ucName: {
type: GraphQLString,
resolve: (source) => source.name.toUpperCase(),
},
currentLocalTime: {
type: 'Date',
resolve: (source) => moment().tz(source.tz).format(),
projection: { tz: true },
},
counter: 'Int',
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 }`],
});
CityTC.addResolver({
kind: 'query',
name: 'findMany',
args: {
filter: `input CityFilterInput {
code: String!
}`,
limit: {
type: 'Int',
defaultValue: 20,
},
skip: 'Int',
},
type: [CityTC],
resolve: async ({ args, context }) => {
return context.someCityDB
.findMany(args.filter)
.limit(args.limit)
.skip(args.skip);
},
});
CityTC.removeField('tz');
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 => {
if (!rp.context.isAdmin) {
throw new Error('You should be admin, to have access to this action.');
}
return next(rp);
});
});
return resolvers;
}
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]

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

License
MIT