Skip to content

Sorting, Includes & Fields

Sorting

ts
await User.crispy()
  .sortByDesc('created_at')      // ?sort=-created_at
  .sortBy('name')                // ?sort=-created_at,name
  .get();

Multi-field sorts compose left to right. Prefix - for descending — handled for you by sortByDesc.

Including relations

ts
await User.crispy()
  .include('posts', 'profile')                    // ?include=posts,profile
  .include('posts.comments')                      // ?include=posts,profile,posts.comments
  .get();

Dot-notation works for nested relations.

Aggregate includes (count / exists / sum / avg / min / max)

Pairs with Spatie's AllowedInclude::count / exists / sum / avg / min / max.

ts
await User.crispy()
  .includeCount('posts')                  // ?include=postsCount
  .includeExists('friends')               // ?include=postsCount,friendsExists
  .includeSum('postsViewsSum')            // server: AllowedInclude::sum('postsViewsSum', 'posts', 'views')
  .includeAvg('postsViewsAvg')
  .includeMin('postsViewsMin')
  .includeMax('postsViewsMax')
  .get();

For sum/avg/min/max, pass the include name declared on the server — the actual aggregate (relation + column) is configured server-side via AllowedInclude::sum($includeName, $relation, $column).

Sparse fieldsets

Reduce payload size by selecting only the columns you need.

ts
await User.crispy()
  .fields('users', 'id', 'name')                  // ?fields[users]=id,name
  .include('posts')
  .fields('posts', 'id', 'title')                 // ?fields[users]=id,name&fields[posts]=id,title
  .get();

Server-side requirement: allowedFields() must whitelist the columns.

Append accessors

Laravel model accessors that aren't in the table:

ts
await User.crispy()
  .append('full_name', 'avatar_url')              // ?append=full_name,avatar_url
  .get();