Overview
The Garnet API supports two pagination styles:
- Offset-based pagination - Traditional page numbers (used in most endpoints)
- Cursor-based pagination - Efficient pagination for large datasets (used in agent and profile listings)
PageArgs
Request parameters for offset-based pagination.
type PageArgs struct {
Page *int `json:"page,omitempty"` // Page number (1-based)
PerPage *int `json:"perPage,omitempty"` // Items per page
}
Paginator
Generic paginated response wrapper.
type Paginator[T any] struct {
Data []T `json:"data"`
PaginatorInfo PaginatorInfo `json:"paginatorInfo"`
}
Array of items for the current page
PaginatorInfo
Pagination metadata for offset-based pagination.
type PaginatorInfo struct {
Total int `json:"total"` // Total number of items
PerPage int `json:"perPage"` // Items per page
CurrentPage int `json:"currentPage"` // Current page (1-based)
LastPage int `json:"lastPage"` // Last page number
From *int `json:"from,omitempty"` // First item index (1-based)
To *int `json:"to,omitempty"` // Last item index (1-based)
}
Total number of items across all pages
Current page number (1-based)
Last available page number
Index of first item on current page (1-based). Null if page is empty.
Index of last item on current page (1-based). Null if page is empty.
Example Usage
// Request second page with 50 items per page
page := 2
perPage := 50
args := types.PageArgs{
Page: &page,
PerPage: &perPage,
}
// Response example
response := types.Paginator[types.Issue]{
Data: []types.Issue{
// 50 issues...
},
PaginatorInfo: types.PaginatorInfo{
Total: 250,
PerPage: 50,
CurrentPage: 2,
LastPage: 5,
From: intPtr(51),
To: intPtr(100),
},
}
Helper Functions
// DecodePageArgs extracts PageArgs from URL query parameters
func DecodePageArgs(v url.Values) PageArgs
// Example: ?page=2&perPage=50
// CalculatePaginatorInfo calculates pagination metadata
func CalculatePaginatorInfo(dataLen, total int, page, perPage *int) PaginatorInfo
CursorPageArgs
Request parameters for cursor-based pagination.
type CursorPageArgs struct {
First *uint // Get first N items
After *string // Cursor to start after
Last *uint // Get last N items
Before *string // Cursor to end before
}
Note: Cannot specify both first and last in the same request.
Methods
IsBackwards() bool - Returns true if paginating backwards (using last or before)
Validator() *validator.Validator - Returns validator for the args
CursorPage
Generic cursor-based paginated response.
type CursorPage[T any] struct {
Items []T `json:"items"`
PageInfo CursorPageInfo `json:"pageInfo"`
}
Array of items for the current page
Cursor pagination metadata
CursorPageInfo
Metadata for cursor-based pagination.
type CursorPageInfo struct {
TotalCount uint `json:"totalCount"`
EndCursor *string `json:"endCursor"`
HasNextPage bool `json:"hasNextPage"`
StartCursor *string `json:"startCursor"`
HasPreviousPage bool `json:"hasPreviousPage"`
}
Total number of items available
Cursor for the last item on this page. Use with after to get the next page.
Whether there are more items after this page
Cursor for the first item on this page. Use with before to get the previous page.
Whether there are items before this page
Example Usage
// First page: get first 50 agents
first := uint(50)
args := types.CursorPageArgs{
First: &first,
}
// Response
response := types.CursorPage[types.Agent]{
Items: []types.Agent{
// 50 agents...
},
PageInfo: types.CursorPageInfo{
TotalCount: 250,
EndCursor: stringPtr("cursor_abc123"),
HasNextPage: true,
StartCursor: stringPtr("cursor_xyz789"),
HasPreviousPage: false,
},
}
// Next page: use endCursor as after
args = types.CursorPageArgs{
First: &first,
After: response.PageInfo.EndCursor,
}
Validation Rules
Cursor pagination has built-in validation:
first must be greater than 0 and not exceed 200
last must be greater than 0 and not exceed 200
- Cannot specify both
first and last in the same request
Sorting
Sort
Sorting parameters for paginated results.
type Sort struct {
Field string `json:"field"` // Field to sort by
Order Order `json:"order"` // Sort order
}
Order
Sort order direction.
type Order string
const (
OrderAsc Order = "asc" // Ascending order
OrderDesc Order = "desc" // Descending order
)
Methods
String() string - Returns string representation
Validate() error - Validates the order is valid
Helper Functions
// DecodeSort extracts Sort from URL query parameters
func DecodeSort(v url.Values) *Sort
// Example: ?sort.field=created_at&sort.order=desc
Example Usage
// Sort by creation date, newest first
sort := types.Sort{
Field: "created_at",
Order: types.OrderDesc,
}
if err := sort.Order.Validate(); err != nil {
// Handle invalid order
}
When to Use Each Style
- Users need to jump to specific pages
- Total count and page numbers are important
- Dataset is relatively small (< 10,000 items)
- Used in: Issues, Events, Webhooks, Project Settings
- Dataset is very large
- Real-time data with frequent inserts
- Only need forward/backward navigation
- Better performance for deep pagination
- Used in: Agents, Profiles
Constants
const (
DefaultPageSize = 20 // Default items per page for offset pagination
maxPageSize = 200 // Maximum items per page for cursor pagination
)