Guide/Building a query
Building a query
QueryBuilder is a fluent facade over a QubeeStore. Every mutator returns this, so a whole
query is one chain. Nothing is sent anywhere until you call generateUri().
The resource
Section titled “The resource”Everything starts here. generateUri() throws without it.
qb.setResource('articles'); // → /articlesqb.setBaseUrl('https://api.dev'); // → https://api.dev/articlesPagination
Section titled “Pagination”qb.setPage(2).setLimit(25);Navigation helpers move relative to the current page and clamp rather than throw:
| Method | Behaviour |
|---|---|
firstPage() |
Jump to page 1. Idempotent |
nextPage() |
Advance one page. No-op on the last page, once known |
previousPage() |
Back one page. No-op on page 1 |
lastPage() |
Jump to the final page. Throws until a response is synced |
goToPage(n) |
Jump to n. Throws InvalidPageNumberError if out of range |
Read-only helpers answer where you are:
qb.currentPage(); // 2qb.hasNextPage(); // trueqb.hasPreviousPage(); // trueqb.isFirstPage(); // falseqb.totalPages(); // 6 — throws until syncedSorting
Section titled “Sorting”import { SortEnum } from '@qubeejs/core';
qb.addSort('createdAt', SortEnum.DESC).addSort('title', SortEnum.ASC);qb.deleteSorts('title');Field selection
Section titled “Field selection”Two different things, and drivers support them independently:
qb.addSelect('id', 'title'); // flat — capabilities.selectqb.addFields('articles', ['id']); // typed — capabilities.fieldsaddSelect() names columns on the primary resource. addFields() names them per model, the
JSON:API-style sparse fieldset.
Relations
Section titled “Relations”qb.addIncludes('author', 'comments'); // capabilities.includesqb.addEmbedded('author', 'name', 'email'); // capabilities.embedded — PostgRESTSearch
Section titled “Search”qb.setSearch('typescript'); // capabilities.searchChaining and resetting
Section titled “Chaining and resetting”const uri = qb .setResource('articles') .addFilter('status', 'published') .addSort('createdAt', SortEnum.DESC) .setLimit(25) .generateUri();
qb.reset(); // back to a pristine stateCapability checks happen immediately
Section titled “Capability checks happen immediately”Every mutator asks the driver first. Calling something the backend cannot express throws at the call site rather than emitting a URI the server silently ignores:
const qb = new QueryBuilder(store, LARAVEL_DRIVER.createRequestStrategy('query'), undefined, 'laravel');
qb.addFilter('status', 'published');// UnsupportedFilterError: The 'laravel' driver does not support filters.See the capability matrix for what each driver supports.
