Composition tool for GraphQL, with helpers to combine multiple resolvers into one, specify
dependencies between fields, and more.
When developing a GraphQL server, it is common to perform some authorization logic on your
resolvers, usually based on the context of a request. With Resolvers Composition you can easily
accomplish that and still make the code decoupled - thus testable - by combining multiple
single-logic resolvers into one.
The following is an example of a simple logged-in authorization logic:
Instead of doing this:
const resolvers = { Query: { myQuery(root, args, context) { // Make sure that the user is authenticated if (!context.currentUser) { throw new Error('You are not authenticated!') } // Make sure that the user has the correct roles if (!context.currentUser.roles || context.currentUser.roles.includes('EDITOR')) { throw new Error('You are not authorized!') } // Business logic if (args.something === '1') { return true } return false } }}
You can do:
const { composeResolvers } = require('@graphql-tools/resolvers-composition')const resolvers = { Query: { myQuery(root, args, context) { if (args.something === '1') { return true } return false } }}const isAuthenticated = () => next => (root, args, context, info) => { if (!context.currentUser) { throw new Error('You are not authenticated!') } return next(root, args, context, info)}const hasRole = (role: string) => next => (root, args, context, info) => { if (!context.currentUser.roles?.includes(role)) { throw new Error('You are not authorized!') } return next(root, args, context, info)}const resolversComposition = { 'Query.myQuery': [isAuthenticated(), hasRole('EDITOR')]}const composedResolvers = composeResolvers(resolvers, resolversComposition)
composeResolvers is a method in @graphql-tools/resolvers-composition package that accepts
IResolvers object and mappings for composition functions that would be run before resolver itself.
Supported Path Matcher Format
The paths for resolvers support * wildcard for types and glob patterns for fields. For example:
*.* - all types and all fields
Query.* - all queries
Query.single - only a single query
Query.{first, second} - queries for first/second
Query.!first - all queries but first
Query.!{first, second} - all queries but first/second
This site uses cookies for analytics and improving your experience.