Dataloaders

What are GraphQL Dataloaders? Please take a look here https://gqlgen.com/reference/dataloaders/

How to create a dataloader?

  1. Create a folder "dataloaders" inside graphql folder
  2. Create file dataloaders.go
package dataloaders

//go:generate dataloaden LoaderName uint64 []*/path/entity.SomeModel/Entity
1
2
3
  1. Generate dataloaders
go generate ./api/<binary>/graphql/dataloaders/...
1
  1. Implement loaders

go generate will create gen.go file that contains loaders skeleton.

func NewLoaders(ctx context.Context) *Loaders {
    return &Loaders{
        VariantsByProductID: LoaderNameLoader{
        maxBatch: 1000,
        wait:     5 * time.Millisecond,
        fetch: func(ids []uint64) ([][]*entity.SomeModel, []error) {
                //Some code here
				return someModelSlice, errors
			},
		}
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
  1. Create middleware and attach Dataloaders to context
  • Create file dataloader.go
func DataLoaders(ginEngine *gin.Engine) {
	ginEngine.Use(func(c *gin.Context) {
		ctx := c.Request.Context()
		ctx = context.WithValue(ctx, key, NewLoaders(ctx))
		c.Request = c.Request.WithContext(ctx)
	})
}
1
2
3
4
5
6
7
  • Add DataLoaders middleware to Gin
  1. Add Retriever to resolvers
// This file will not be regenerated automatically.
//go:generate go run github.com/99designs/gqlgen
// It serves as dependency injection for your app, add any dependencies you require here.

type Resolver struct {
    DataLoaders dataloaders.Retriever
}
1
2
3
4
5
6
7
  1. git add & git commit

How to use a dataloader?

  1. Accessing Dataloaders - dataloaders can be accessed using Retreive function in resolvers.
func (r *someResolver) SomeMethod(ctx context.Context, obj *model.SomeModel) ([]*model.SomeOtherModel, error) {
	if !hitrix.Validate(ctx, nil) {
		return nil, nil
	}

	someOtherModel, err := r.DataLoaders.Retrieve(ctx).VariantsByProductID.Load(obj.ID)

	if err != nil {
		return nil, err
	}

	return someOtherModel, nil
}
1
2
3
4
5
6
7
8
9
10
11
12
13