variables for a mutation query are not being passed to resolver
Sewdn opened this issue · 3 comments
Hi,
Maybe I'm missing something, but it seems to me that Input Type objects are not being passed to the implemeting mutation resolvers.
getGraphQLParameters
is parsing the variables correctly (and the input is confirmed as being a valid inpt type for the specific mutation).
When the operation
, query
and variables
are passed to the async method processRequest
, the resolver is hit, but the mathod doesnt receive any variables...
Some example code:
...
const { operationName, query, variables } = getGraphQLParameters(request);
console.log({ operationName, query, variables });
const result = await processRequest({
operationName,
query,
variables,
request,
schema,
});
if (result.type === 'RESPONSE') {
result.headers.forEach(({ name, value }) => res.setHeader(name, value));
res.status(result.status);
res.json(result.payload);
} else {
res.status(400);
res.json({ error: 'no support for multipart responsed or streams' });
}
...
import { makeExecutableSchema } from '@graphql-tools/schema';
import typeDefs from './typedefs.generated';
import resolvers from './resolvers';
export const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
import {
Claim,
Policy,
Customer,
ClaimInput,
ClaimCreateResponse,
// Resolvers,
} from '../types.generated';
import { Claims, Policies, Customers } from '../stores';
import { claims as claimsResolvers } from './claims';
const resolvers = {
Query: {
allClaims: () => Claims.findAll(),
allPolicies: () => Policies.findAll(),
allCustomers: () => Customers.findAll(),
},
Mutation: {
createClaim: (claim: ClaimInput): Promise<ClaimCreateResponse> => Claims.create(claim),
},
...claimsResolvers,
Policy: {
claims: ({ id }: Policy): Claim[] => Claims.findByPolicyId(id),
customer: ({ customerId }: Policy): Customer | null => Customers.get(customerId),
},
Customer: {
policies: ({ id }: Customer): Policy[] => Policies.findByCustomerId(id),
},
};
export default resolvers;
import { find, filter } from 'lodash';
import { Claim, ClaimInput, ClaimCreateResponse } from '../types.generated';
import { validate } from '../validators';
import { claims as claimStubs } from './data';
const Claims = {
get: (id: string): Claim | null => find(claimStubs, { id }) || null,
findAll: (): Claim[] => claimStubs,
findByPolicyId: (_id: string): Claim[] => filter(claimStubs, { policyId: _id }),
create: async (claim: ClaimInput): Promise<ClaimCreateResponse> => {
// validate input
console.log(claim);
if (validate('ClaimInput')(claim)) {
return {
claim: {
...claim,
id: 'generatedId',
},
};
} else {
throw new Error('not valid');
}
},
};
export default Claims;
Hi @Sewdn. A GraphQL resolver takes four parameters: the parent value, an arguments object, a context object and a GraphQLResolveInfo
object. Your resolver, however, is written like this:
createClaim: (claim: ClaimInput): Promise<ClaimCreateResponse> => Claims.create(claim),
Assuming claim
is the name of an argument on the createClaim
field, you should instead do:
createClaim: (args): Promise<ClaimCreateResponse> => Claims.create(args.claim),
Thanks for your swift response!
It was indeed the second parameter that I needed, to pass on the typed argument; (I had been testing with the first parameter).
Mutation: {
createClaim: (_: any, args: MutationCreateClaimArgs): Promise<ClaimCreateResponse> => {
return Claims.create(args.input);
},
},
What is the type of this first parameter? As it is the parent value for the field resolver of an entity, for a mutation this is somewhat misleading for a mutation resolver, since this would be the root entity, and thus an empty {}
object of any
type?
For root fields, regardless of whether they are on the Query
or Mutation
root type, the parent value will always be the root value. You can provide this value using the rootValueFactory
option, in which case the value will be whatever the factory returns. If the option is omitted, rootValue is simply an empty object.