Skip to content

Go Pagination for SQLBoiler and gqlgen (GraphQL)

License

Notifications You must be signed in to change notification settings

nrfta/go-paging

Repository files navigation

go-paging

Go pagination for SQLBoiler and gqlgen (GraphQL).

Install

go get -u "github.com/nrfta/go-paging"

Usage

  1. Add this GraphQL schema to your project.

  2. Add models to gqlgen.yml:

models:
  PageArgs:
    model: github.com/nrfta/go-paging.PageArgs

  PageInfo:
    model: github.com/nrfta/go-paging.PageInfo
  1. Add PageInfo Resolver for gqlgen
package resolvers

import (
	"github.com/nrfta/go-paging"
)

func (r *RootResolver) PageInfo() PageInfoResolver {
	return paging.NewPageInfoResolver()
}
  1. Full Example

This assumes you have the following GraphQL schema:

type Post {
  id: ID!
  name: String
}

type PostEdge {
  cursor: String
  node: Post!
}

type PostConnection {
  edges: [PostEdge!]!
  pageInfo: PageInfo!
}

type Query {
  posts(page: PageArgs): PostConnection!
}

Note that PageArgs and PageInfo is defined in schema.graphql and your should copy it to your project.

Here is what the resolver function would look like:

package resolvers

import (
  "context"

	"github.com/nrfta/go-paging"
	"github.com/volatiletech/sqlboiler/v4/queries/qm"

	"github.com/my-user/my-app/models"
)

func (r *queryResolver) Posts(ctx context.Context, page *paging.PageArgs) (*PostConnection, error) {
	var mods []qm.QueryMod

	totalCount, err := models.Posts().Count(ctx, DB)
	if err != nil {
		return &PostConnection{
			PageInfo: paging.NewEmptyPageInfo(),
		}, err
	}

	paginator := paging.NewOffsetPaginator(page, totalCount)
	mods = append(mods, paginator.QueryMods()...)

	records, err := models.Posts(mods...).All(ctx, DB)
	if err != nil {
		return &PostConnection{
			PageInfo: paging.NewEmptyPageInfo(),
		}, err
	}

	result := &PostConnection{
		PageInfo: &paginator.PageInfo,
	}

	for i, row := range records {
		result.Edges = append(result.Edges, &PostEdge{
			Cursor: paging.EncodeOffsetCursor(paginator.Offset + i + 1),
			Node:   row,
		})
	}
	return result, nil
}

License

This project is licensed under the MIT License.