# Resolver
A resolver is a class that hosts query, mutation or subscription.
# @Query and @Mutation
These two decorators work in the same way, except that one declares a field in your Query type and the other in your Mutation type.
The final result is that the @Field decorator declares a field in its respective type (type Query or type Mutation), it then accepts the same parameters as @Field (details).
@ObjectType()
class Response {
// ...
}
@Resolver()
class Resolver {
@Query()
queryMe(): Response {
// ...
}
@Mutation()
mutateMe() {
// ...
}
}
Will give in SDL:
type Query {
queryMe: Response
}
type Mutation {
mutateMe: Response
}
# @Arg and @Args
Your query, mutation and subscription can have arguments, to declare them there are two decorators:
@Arg, states a single argument@Args, declares a set of arguments using an@InputType.
Arguments are converted to class instances pending if they have a related class.
# @Arg
@Resolver()
class Resolver {
@Query()
queryMe(@Arg("myArg") arg: string): Response {
// ...
}
}
Will give in SDL:
type Query {
queryMe(arg: String): Response
}
# @Args
@InputType()
class Args {
@Field()
count: number;
@Field()
name: string;
}
@Resolver()
class Resolver {
@Query()
queryMe(@Args() args: Args): Response {
// ...
}
}
Will give in SDL:
type Query {
queryMe(count: Float, name: String): Response
}
# Subscriptions
It's a bit different for a subscription, this one also works as @Query and @Mutation. Subscriptions will be added to the GraphQL type Subscription. However, it needs to indicate a subscribe function in its parameters.
So you can choose the desired library for your subscriptions, here is an example with graphql-subscriptions.
When you use
PubSub.publish, the value of the payload is injected intoContext.source.
import { Context } from "graphql-composer";
import { PubSub } from "graphql-subscriptions";
const pubsub = new PubSub();
@ObjectType()
class Response {
// ...
}
@Resolver()
class Resolver {
Subscription({
// Executed when the client subscribe to the event, to determine the topic
subscription: (args) => pubsub.asyncIterator("NOTIFICATION"),
})
// Executed when the pubsub publish to the specified topic
mySubscription(ctx: Context): Response {
// The payload is injected into ctx.source
console.log(ctx.souce);
// ...
}
@Query()
trigger(): Response {
pubsub.publish("NOTIFICATION", { payload: "my data" });
// ...
}
}
For people familiar with how to do things with the graphql module, this would look like this:
const resolvers = {
Subscription: {
subscribe: () => pubsub.asyncIterator("NOTIFICATION"),
resolve: () => {
console.log("Triggered");
// ...
}
}
}
Which gives in SDL:
type Subscription {
mySubscription: Response
}
# The Context object
The Context<BodyType = any, SourceType = any> object is injected after your arguments into a method, it contains all the information of the request:
| Property | Type | Description |
|---|---|---|
| body | BodyType (any) | The response sent to the client |
| field | Field | Contains the reference to the Field object in graphql-compose, giving you access to all the information in the field |
| context | any | The GraphQL context |
| info | GraphQLResolveInfo | GraphQL's info object |
| source | SourceType (any) | GraphQL source object, the payload of a subscription |
| rawArgs | any | arguments not converted to pending class, arguments as is |
# Return a result
You can return a result in two different ways:
- Using
return(can be restrictive when using middleware with thenextfunction) - By assigning
Context.bodyto a value
import { Context } from "graphql-composer";
@ObjectType()
class Response {
// ...
}
@Resolver()
class Resolver {
@Query()
returned(): Response {
return new Response();
}
@Query()
ctxBody(context: Context) {
context.body = new Response();
}
}
← Field Middlewares →