Description
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.