Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
graphql-compose
Advanced tools
GraphQL schema builder from different data sources with middleware extensions.
graphql-compose is a toolkit for generating and working with GraphQL schemas in a more flexible and composable way. It provides utilities to create GraphQL types, resolvers, and schemas with ease, allowing for a more modular and maintainable approach to building GraphQL APIs.
Schema Creation
This feature allows you to create a GraphQL schema by adding fields to the Query type. The example demonstrates adding a simple 'hello' field that returns a string.
const { schemaComposer } = require('graphql-compose');
schemaComposer.Query.addFields({
hello: {
type: 'String',
resolve: () => 'Hello, world!',
},
});
const schema = schemaComposer.buildSchema();
Type Composers
Type Composers allow you to define GraphQL object types and their fields in a modular way. The example shows how to create a 'User' type and add a custom resolver to it.
const { schemaComposer } = require('graphql-compose');
const UserTC = schemaComposer.createObjectTC({
name: 'User',
fields: {
id: 'ID!',
name: 'String',
},
});
UserTC.addResolver({
name: 'findById',
type: 'User',
args: { id: 'ID!' },
resolve: ({ source, args, context, info }) => {
// resolver logic here
},
});
Resolver Composition
Resolver Composition allows you to add multiple resolvers to a type, making it easier to manage complex query logic. The example shows how to add 'findById' and 'findByName' resolvers to the 'User' type.
const { schemaComposer } = require('graphql-compose');
const UserTC = schemaComposer.getOrCreateOTC('User', {
fields: {
id: 'ID!',
name: 'String',
},
});
UserTC.addResolver({
name: 'findById',
type: UserTC,
args: { id: 'ID!' },
resolve: ({ source, args, context, info }) => {
// resolver logic here
},
});
UserTC.addResolver({
name: 'findByName',
type: UserTC,
args: { name: 'String' },
resolve: ({ source, args, context, info }) => {
// resolver logic here
},
});
graphql-tools is a set of utilities from Apollo for creating and manipulating GraphQL schemas. It provides schema stitching, schema delegation, and other advanced features. Compared to graphql-compose, graphql-tools is more focused on schema stitching and merging, while graphql-compose offers a more composable and modular approach to schema and resolver creation.
type-graphql is a library that allows you to define your GraphQL schema using TypeScript classes and decorators. It provides a more type-safe approach to schema creation compared to graphql-compose, which is more flexible and JavaScript-centric. type-graphql is ideal for TypeScript users who want to leverage decorators and strong typing.
nexus is a code-first GraphQL schema construction library for TypeScript and JavaScript. It allows you to define your schema using a fluent API and integrates well with the Prisma ORM. Compared to graphql-compose, nexus offers a more opinionated and integrated approach, especially when used with Prisma, while graphql-compose provides more flexibility and composability.
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.
Resolver
s – the named graphql fieldConfigs, which can be used for finding, updating, removing recordsResolver
sOutputType
to InputType
projection
parser from ASTGraphQL schema language
for defining simple typesDate
, Json
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.
graphql-compose
Relay
specific things, like Node
type and interface, globalId
, clientMutationId
.connection
Resolver from findMany
and count
Resolvers.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();
This project exists thanks to all the people who contribute.
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]
FAQs
GraphQL schema builder from different data sources with middleware extensions.
The npm package graphql-compose receives a total of 402,038 weekly downloads. As such, graphql-compose popularity was classified as popular.
We found that graphql-compose demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.