Skip to content

Support for defining field extensions property in Apollo resolvers #1279

Closed
@mattdean-digicatapult

Description

@mattdean-digicatapult

What I'm trying to do:

My end goal is to implement DoS protection using graphql-query-complexity and more specifically using the fieldExtensionsEstimator from that library. This makes use of the field extensions property in graphql-js to label individual fields with a complexity cost function allowing for a very expressive cost calculation mechanism.

The problem

As far as I can tell there is no supported/documented mechanism for defining field extensions in graphql-tools so I would have to define my schema using graphql-js directly. Having said that the following does work:

const resolvers = {
  Query: {
    tests: {
      resolve: (_, args) => {
        const result = []
        for (let index = args.startIndex; index < args.endIndex; index++) {
          result.push({ index })
        }
        return result
      },
      extensions: {
        // complexity field extension used by fieldExtensionsEstimator
        complexity: ({ args, childComplexity }) => childComplexity * (args.endIndex - args.startIndex),
      },
    },
  }
}

A more complete working example can be found at digicatapult/graphql-complexity-experiment.

The problem therefore is that the extensions property in the above is both not documented and not included in the typings.

Solution

Firstly modify the interface IResolverOptions to include the extensions property like:

export interface IResolverOptions<TSource = any, TContext = any, TArgs = any> {
  fragment?: string;
  resolve?: IFieldResolver<TSource, TContext, TArgs>;
  subscribe?: IFieldResolver<TSource, TContext, TArgs>;
  extensions?: Readonly<Record<string, any>>;
  __resolveType?: GraphQLTypeResolver<TSource, TContext>;
  __isTypeOf?: GraphQLIsTypeOfFn<TSource, TContext>;
}

to match the equivalent property in graphql-js. Secondly this behaviour should be documented in the apollo-server docs.

Can I do this?

If the above sounds good then I would be happy to submit a PR for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions