Custom Mutations
As a product gets more complicated, the need to eventually add custom mutations to the schema arises. This shows how to do so.
Auth Example
A common thing for a lot of applications is to implement authentication to log the user in. This shows a possible way to implement it:
src/graphql/mutations/auth.ts
@gqlInputObjectType()
export class UserAuthInput {
@gqlField({
class: 'UserAuthInput',
type: GraphQLString,
})
emailAddress: string;
@gqlField({
class: 'UserAuthInput',
type: GraphQLString,
})
password: string;
constructor(emailAddress: string, password: string) {
this.emailAddress = emailAddress;
this.password = password;
}
}
@gqlObjectType()
export class UserAuthPayload {
@gqlField({
class: "UserAuthPayload",
type: GraphQLID,
})
viewerID: ID;
constructor(viewerID: ID) {
this.viewerID = viewerID;
}
}
export class AuthResolver {
@gqlMutation({
class: "AuthResolver",
name: "userAuth",
type: UserAuthPayload,
async: true,
args: [
gqlContextType(),
{
name: "input",
type: "UserAuthInput",
},
]
})
async userAuth(
context: RequestContext,
input: UserAuthInput,
): Promise<UserAuthPayload> {
return new UserAuthPayload("1");
}
}
This updates the GraphQL schema as follows:
src/graphql/generated/schema.gql
type Mutation {
userAuth(input: UserAuthInput!): UserAuthPayload!
}
type UserAuthPayload {
viewerID: ID!
}
input UserAuthInput {
emailAddress: String!
password: String!
}
Here's what's happening here:
- This adds a new input type
UserAuthInput
to the GraphQLSchema represented by the classUserAuthInput
. UserAuthInput
object has 2 fields:emailAddress
of typeString
password
of typeString
- This adds a new object type
UserAuthPayload
to the GraphQLSchema represented by the classUserAuthPayload
UserAuthPayload
object has 1 field:viewerID
of typeID
- New field
userAuth
added toMutation
Type which takesUserAuthInput
input and returnsUserAuthPayload
.
This uses the following concepts to implement this:
gqlMutation
This adds a new field to the GraphQL Mutation
type. See example usage above.
Accepts the following options which overlap with gqlField:
class
for the name of the class the function is defined in.name
for the name of the GraphQL fielddescription
of the fieldtype
: type returned by the field