Giter Club home page Giter Club logo

graphql-resolvers's Introduction

GraphQL Resolvers

Resolver composition library for GraphQL

build status coverage npm version sponsored by Taller


This library consists of simple but well tested helper functions for combining other functions into more specialized ones.

Installation

This package is available on npm as: graphql-resolvers

npm install graphql-resolvers

You should consider using yarn, though.

Motivation

Many times we end-up repeating lots of logic on our resolvers. Access control, for instance, is something that can be done in the resolver level but just tends to end up with repeated code, even when creating services for such a task. This package aims to make it easier to build smart resolvers with logic being reusable and split in small pieces. Think recompose, but for GraphQL resolvers.

Documentation

Read full documentation here

Similar projects

Besides being inspired by some functional libraries out there, this project has some goals in common with other projects:

While graphql-resolvers follows the functional paradigm, apollo-resolvers project solves some problems using an opinionated and OOP approach. Furthermore, the second also solves other problems which graphql-resolvers does not intend to work on, such as solving circular references on the resolver's context.

At first, my idea was to incorporate the combineResolvers method into the wider project graphql-tools. That may yet happen some day, but I think people my not want to install the whole graphql-tools project when wanting this simple package's helper on their projects. Also, combineResolvers should work pretty fine with resolvers binded into graphql/types too.

graphql-resolvers's People

Contributors

dependabot[bot] avatar lucasconstantino avatar nchaulet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

graphql-resolvers's Issues

Typescript: Types of parameters 'info' and 'info' are incompatible.

The full error is:

 Type 'IFieldResolver<any, any, any, any>' is not assignable to type 'Resolver<Maybe<any[]>, {}, any, {}> | undefined'.
    Type 'IFieldResolver<any, any, any, any>' is not assignable to type 'ResolverFn<Maybe<any[]>, {}, any, {}>'.
    Types of parameters 'info' and 'info' are incompatible.

    Type 'GraphQLResolveInfo' is not assignable to type 'GraphQLResolveInfo & { mergeInfo?: MergeInfo | undefined;}'.
        Type 'import(" ./node_modules/graphql/type/definition").GraphQLResolveInfo'  assignable to e 'import(" ./node_modules/@types/graphql-resolvers/node_modules/graphql/type/definition").GraphQLResolveInfo'.
        Types of property 'returnType' are incompatible.
            Type 'import(" ./node_modules/graphql/type/definition").GraphQLOutputType' is not assignable to type 'import(" ./node_modules/@types/graphql-resolvers/node_modules/graphql/type/definition").GraphQLOutputType'.

            Type 'GraphQLScalarType' is not assignable to type 'GraphQLOutputType'.
                Type 'GraphQLScalarType' is missing the following properties from type 'GraphQLEnumType': getValues, getValue`

but I thing the first issue is:
Types of parameters 'info' and 'info' are incompatible.

It looks like the Types for info in index.d.ts from the types for your library: https://www.npmjs.com/package/@types/graphql-resolvers Someone must have published them :-) thanks @rwieruch

I tried a simple change to the index.d.ts
export type IFieldResolver<TSource, TContext, TArgs = Record<string, any>, TReturn = any> = ( source: TSource, args: TArgs, context: TContext, info: GraphQLResolveInfo & { mergeInfo?: MergeInfo | undefined } | any, ) => TReturn;
Luis Felipe Zaguini
by adding the | any on the info type
I'm hoping someone who is versatile with this repo and types will be able to help.

Docs don't show resolveDependees

The docs do not show an example of resolveDependees. I am getting an error when trying to create a resolver the following way:

const poolShareValue = pipeResolvers(
  resolveDependees(['totalPoolShares', 'poolValue']),
  ([totalPoolShares, poolValue]) => {
    const ethPerShare = totalPoolShares.toNumber() > 0 ? parseFloat(utils.formatEther(poolValue)) / totalPoolShares.toNumber() : 0; // in eth
    const value = utils.parseEther(ethPerShare.toString()); // in wei
    return value
  }
)

When I tried to set poolShareValue as a resolver, my app throws an error:

Uncaught Error: Error!: Error: Network error: Cannot read property '_fields' of undefined
    at Object.children (Pool.js:129)
    at finish (react-apollo.esm.js:434)
    at Query.render (react-apollo.esm.js:441)
    at finishClassComponent (react-dom.development.js:15320)
    at updateClassComponent (react-dom.development.js:15275)
    at beginWork (react-dom.development.js:16265)
    at performUnitOfWork (react-dom.development.js:20285)
    at workLoop (react-dom.development.js:20326)
    at HTMLUnknownElement.callCallback (react-dom.development.js:147)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:196)
    at invokeGuardedCallback (react-dom.development.js:250)
    at replayUnitOfWork (react-dom.development.js:19509)
    at renderRoot (react-dom.development.js:20439)
    at performWorkOnRoot (react-dom.development.js:21363)
    at performWork (react-dom.development.js:21273)
    at performSyncWork (react-dom.development.js:21247)
    at requestWork (react-dom.development.js:21102)
    at scheduleWork (react-dom.development.js:20915)
    at Object.enqueueForceUpdate (react-dom.development.js:11633)
    at Query.push../node_modules/react/cjs/react.development.js.Component.forceUpdate (react.development.js:355)

running "afterware"

With combine we can add handlers to run before the main resolver. Useful for authentication checks and such.

I think it would be nice if we could also run some handlers after the main resolver. Think about credit transactions.

combineResolvers(reserveFunds, performAction, chargeFunds)

Problem when resolving a dependent when requiring only the dependent

From what I understood of the code, info.rootValue is passed as argument to the parent resolver when the dependee has not been resolved yet, but I couldn't find on the code where this info.rootValue is set and neither could I find on the docs if I should set this myself.

? info.parentType._fields[dependeeName].resolve(info.rootValue, args, context, info)

Can you help me with this?

Allow combineResolvers and pipeResolvers to reject

First off, thanks for this very useful library.

The issue I'm running into is with how combineResolvers and pipeResolvers have a .catch that returns the error, rather than allowing the error to bubble up. This seems to be counter to how a regular resolver would work.

Currently, as I user of the library, If I want to act on an error occurring in the resolver, I have to use instanceof on the resolved value and if it's an Error, act appropriately. If I want to allow graphql to just add the error to the errors array in the response, then I have to check with instanceof and if Error re-throw.

Perhaps I'm using it wrong, but I seems like it should be up to the code using the library to decide how error should be handled.

resolveDependee `obj` is always `rootValue`

Hi, I am having some trouble with resolveDependee, this function call the dependant resolver but not with the right object as first argument but the rootValue of my schema.

combineResolvers always throws "cannot read property 'apply' of undefined"

I am trying to attach the following guard:

export const isSupplier=(_,__,{me})=>{
    
  me.role==="supplier" ? skip : new ForbiddenError('Not authenticated as supplier.');
}

To a resolver, like this:

addProductNow:combineResolvers(
            isSupplier,
            async (_,{name,price,description,url,stock},{dataSources,me})=>{

            const supplierId=me.id
            console.log(supplierId)
            const supplier=await dataSources.SupplierAPI.findSupplierById(supplierId)
            
            const newProduct=await dataSources.ProductAPI.addProduct(name,price,description,url,stock,supplierId,{ttlInSeconds:60*20})
            return newProduct
        }),

Yet it always returns the error "cannot read property 'apply' of undefined". I have tried to log something in the guard , yet it seems like it never gets executed. After removing the guard from the resolver everything works fine and logging 'me' shows the expected value. Am I doing something wrong ? Thanks !

TypeScript: Property 'mergeInfo' is missing in type 'GraphQLResolveInfo' but required in type '{ mergeInfo: MergeInfo; }

I am using this library and for the last year I loved it. Now I am using it in a TypeScript GraphQL Server with @types/graphql-resolvers.

All my types are generated via graphql-codegen. Without combineResolvers, all types evaluate just fine. If I am using a combined resolver though, I get:

Type 'IFieldResolver<any, any, { courseId: COURSE; bundleId: BUNDLE; }>' is not assignable to type 'ResolverFn<any, {}, ResolverContext, RequireFields<MutationCreateFreeCourseArgs, "courseId" | "bundleId">> | StitchingResolver<...> | undefined'.
  Type 'IFieldResolver<any, any, { courseId: COURSE; bundleId: BUNDLE; }>' is not assignable to type 'ResolverFn<any, {}, ResolverContext, RequireFields<MutationCreateFreeCourseArgs, "courseId" | "bundleId">>'.
    Types of parameters 'info' and 'info' are incompatible.
      Type 'GraphQLResolveInfo' is not assignable to type 'GraphQLResolveInfo & { mergeInfo: MergeInfo; }'.
        Property 'mergeInfo' is missing in type 'GraphQLResolveInfo' but required in type '{ mergeInfo: MergeInfo; }'.ts(2322)
Interfaces.d.ts(59, 5): 'mergeInfo' is declared here.
gen-types.ts(288, 3): The expected type comes from property 'createFreeCourse' which is declared here on type 'WithIndex<{ _?: ResolverFn<any, {}, ResolverContext, {}> | StitchingResolver<any, {}, ResolverContext, {}> | undefined; ... 8 more ...; createAdminCourse?: ResolverFn<...> | ... 1 more ... | 

Whereas I think the crucial part is:

Property 'mergeInfo' is missing in type 'GraphQLResolveInfo' but required in type '{ mergeInfo: MergeInfo; }'.ts(2322)

Could it be that the 4th argument of a resolver isn't evaluated in the TS version of this library?


Something related in another library: https://github.com/prisma-labs/graphql-middleware/pull/29/files

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.