Skip to content

Queries

All queries are auto-generated by @GqlResolver. This page shows what each query looks like and how to use it.

List pagination

Three pagination strategies configured via queries.list.pagination on the resolver. Only one per resolver.

Cursor (default)

Flat items array with cursor-based navigation. Most ergonomic for linear pagination.

@GqlResolver(PostEntity, {
queries: { list: { pagination: 'cursor' } },
})
query {
posts(
first: 10
after: "eyJ..."
where: { published: { eq: true } }
orderBy: [{ createdAt: desc }]
) {
items {
id
title
author {
fullName
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
}

Arguments:

ArgumentTypeDefaultDescription
firstInt20Number of items to return
afterString-Cursor from previous page
where{Entity}WhereInput-Filter conditions
orderBy[{Entity}OrderByInput!]-Sort order (array)

The client passes pageInfo.endCursor as after for the next page. The resolver automatically appends the primary key to orderBy for stable cursor pagination. totalCount is lazy - the count query only runs if the client selects it.

Offset

Classic limit/offset. Familiar if you’re coming from REST.

@GqlResolver(PostEntity, {
queries: { list: { pagination: 'offset' } },
})
query {
posts(limit: 20, offset: 40, where: { published: { eq: true } }, orderBy: [{ createdAt: desc }]) {
items {
id
title
}
totalCount
hasMore
}
}

Arguments:

ArgumentTypeDescription
limitIntNumber of items to return
offsetIntNumber of items to skip
where{Entity}WhereInputFilter conditions
orderBy[{Entity}OrderByInput!]Sort order (array)

hasMore is true when the number of returned items equals the limit.

Cursor with edges (Relay-style)

Full edges-and-nodes wrapping with a cursor per node. Use when you need to resume pagination from an arbitrary item mid-page, or for Relay client compatibility.

@GqlResolver(PostEntity, {
queries: { list: { pagination: 'cursor-edges' } },
})
query {
posts(first: 10, after: "eyJ...") {
edges {
node {
id
title
author {
fullName
}
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
}

Choosing a mode

  • cursor - default. Simplest for clients, works for 99% of cases. Safe on any dataset size.
  • offset - when you need “jump to page N” or visible total page count. Only for small-to-medium tables - avoid on huge datasets.
  • cursor-edges - when you need per-node cursors or Relay compatibility.

Find by ID

query {
post(id: 1) {
id
title
content
author {
id
fullName
}
comments {
id
text
}
}
}

Returns the entity or null. Throws NotFoundException internally (translated to a GraphQL error) if not found.

Count

query {
postsCount(where: { published: { eq: true } })
}

Returns an integer. Accepts the same where input as list queries.

Aggregate

query {
postsAggregate(
where: { published: { eq: true } }
groupBy: ["authorId"]
_count: true
_avg: { authorId: true }
_min: { createdAt: true }
_max: { createdAt: true }
) {
data
}
}

Arguments:

ArgumentTypeDescription
where{Entity}WhereInputFilter before aggregation
groupBy[String!]Fields to group by
_countBooleanInclude record count
_sum{Entity}AggregateNumericFieldsInputSum numeric fields
_avg{Entity}AggregateNumericFieldsInputAverage numeric fields
_min{Entity}AggregateAllFieldsInputMinimum across all fields
_max{Entity}AggregateAllFieldsInputMaximum across all fields

_sum and _avg accept only numeric fields. _min and _max accept all scalar fields.

Filtering

Filters use the where argument with type-safe filter inputs. See Types for all available filter operators.

Basic filtering

query {
posts(where: { published: { eq: true } }) { ... }
}

Combining filters

query {
posts(where: {
AND: [
{ title: { contains: "GraphQL", mode: insensitive } }
{ published: { eq: true } }
]
}) { ... }
}

Relation filters

# posts that have at least one comment containing "great"
query {
posts(where: {
comments: { some: { text: { contains: "great" } } }
}) { ... }
}
# users with no posts
query {
users(where: {
posts: { none: {} }
}) { ... }
}

Ordering

Sort by multiple fields. Supports nested ordering through one-to-one relations.

query {
posts(orderBy: [{ createdAt: desc }, { title: asc }]) { ... }
}
# nested ordering through relation
query {
posts(orderBy: [{ author: { lastName: asc } }]) { ... }
}