Field Resolvers
We'll be working with the below Post struct for this section.
type Post struct {    ID       groot.ID  `json:"id"`    Title    string    `json:"title"`    Author   User      `json:"author"`    Comments []Comment `json:"comments"`    // this field will not be in the graphql schema    AuthorID string    `json:"-"`}Resolver Method#
The resolver for a field is defined the method on the struct with name Resolve{field-name}.
The resolvers return type must be (FieldType, error) if you want to return a value, or if you want to return a thunk (a function returned by a function), it must be (func() (FieldType, error), error). The method should be defined on the value struct (Post) and not the pointer of the struct (*Post).
The method signature of the resolver can be any of the following:
- ()- No Arguments
- (args ArgsStruct)- Arguments to accept from the API
- (ctx context.Context)- Context of a request
- (info graphql.ResolverInfo)- Info about the GraphQL request
- (args ArgsStruct, ctx context.Context)
- (args ArgsStruct, info graphql.ResolverInfo)
- (ctx context.Context, info graphql.ResolverInfo)
- (args ArgsStruct, ctx context.Context, info graphql.ResolverInfo)
For example, we can define a resolver for Author like below:
func (post Post) ResolveAuthor() (User, error) {    return db.GetUser(post.AuthorID)    loader := loader.UserLoaderFromCtx(ctx)    user, err := loader.Load(post.AuthorID)    return user, err}
// Returning a thunk with dataloaderfunc (post Post) ResolveAuthor() (func() (User, error), error) {    thunk := userLoader.Load(post.AuthorID)    return func() (User, error) {        return thunk(), nil    }, nil}Don't worry about making a mistake with the argument or return types, Groot will almost always catch it and panic.
Accepting Arguments#
Say we want to accept the argument first, and after for the comments field for pagintion. First, we need to define a struct with the arguments.
type PaginationArgs struct {    First string `json:"first"`    After string `json:"after"`}Next, we can accept these arguments in the resolver method like below:
func (post Post) ResolveComments(args PaginationArgs) ([]Comment, error) {    comments, err := db.GetPostComments(post.Id, args.First, args.After)    return comments, err}You can also accept nested structures like below:
type BarInput struct {    BarText string `json:"barText"`}
type FooArgs struct {    FooText string   `json:"fooText"`    Bar     BarInput `json:"bar"`}
func (m Mutation) ResolveNewFoo(args FooArgs) (Foo, error) {    return db.CreateFoo(args)}For the above example, Groot will create an input type named BarInput and reference that in the argument field type.