# Ordering
# Client Controlled Ordering
To enable clients to control the ordering, use @orderBy on an argument of a field that is backed by a database query.
type Query {
posts(orderBy: _ @orderBy(columns: ["posted_at", "title"])): [Post!]! @all
}
The type of the argument can be left blank as _
,
as Lighthouse will automatically generate an input that takes enumerated column names,
together with the SortOrder
enum, and add that to your schema:
"Order by clause for Query.posts.orderBy."
input QueryPostsOrderByOrderByClause {
"The column that is used for ordering."
column: QueryPostsOrderByColumn!
"The direction that is used for ordering."
order: SortOrder!
}
"Allowed column names for Query.posts.orderBy"
enum QueryPostsOrderByColumn {
POSTED_AT @enum(value: "posted_at")
TITLE @enum(value: "title")
}
"Directions for ordering a list of records."
enum SortOrder {
"Sort records in ascending order."
ASC
"Sort records in descending order."
DESC
}
Querying a field that has an orderBy
argument looks like this:
{
posts(orderBy: [{ column: POSTED_AT, order: ASC }]) {
title
}
}
# Secondary Ordering
You may pass more than one sorting option to add a secondary ordering.
{
posts(
orderBy: [{ column: POSTED_AT, order: ASC }, { column: TITLE, order: DESC }]
) {
title
}
}
# Reuse Columns Enum
To re-use a list of allowed columns, define your own enumeration type and use the columnsEnum
argument instead of columns
:
type Query {
allPosts(orderBy: _ @orderBy(columnsEnum: "PostColumn")): [Post!]! @all
paginatedPosts(orderBy: _ @orderBy(columnsEnum: "PostColumn")): [Post!]!
@paginate
}
"A custom description for this custom enum."
enum PostColumn {
# Another reason why you might want to have a custom enum is to
# correct typos or bad naming in column names.
POSTED_AT @enum(value: "postd_timestamp")
TITLE @enum(value: "title")
}
Lighthouse will still automatically generate the necessary input types and the SortOrder
enum.
Instead of generating enums for the allowed columns, it will simply use the existing PostColumn
enum.
# Ordering By Relations
You can allow clients to order a list of models by an aggregated value of their relations. You must specify which relations and which of their columns are allowed.
type Query {
users(
orderBy: _
@orderBy(relations: [{ relation: "tasks", columns: ["difficulty"] }])
): [User!]! @all
}
Lighthouse will automatically generate the appropriate input types and enum values.
{
users(
orderBy: [
{ tasks: { aggregate: COUNT }, order: ASC }
{ tasks: { aggregate: MAX, column: DIFFICULTY }, order: DESC }
]
) {
id
}
}
# Predefined Ordering
To predefine a default order for your field, use @orderBy on a field:
type Query {
latestUsers: [User!]! @all @orderBy(column: "created_at", direction: DESC)
}
Clients won't have to pass any arguments to the field and still receive ordered results by default.