Feathers Driver
ArchivedThese are the docs for ng-qubee 3.8. Read the 4.0 docs for @qubeejs/angular.
Targets FeathersJS — the realtime/REST application framework for Node.js, with the dollar-prefixed query syntax shared by all Feathers database adapters (@feathersjs/knex, @feathersjs/mongodb, @feathersjs/memory, …).
Configure
Section titled “Configure”import { DriverEnum, provideNgQubee } from 'ng-qubee';
bootstrapApplication(AppComponent, { providers: [provideNgQubee({ driver: DriverEnum.FEATHERS })]});Wire format
Section titled “Wire format”| Concern | Output |
|---|---|
| Filters (single value) | field=value (bare exact match) |
| Filters (multi-value) | field[$in][0]=v1&field[$in][1]=v2 |
| Operator filters | field[$op]=value — see below |
| Sort | $sort[field]=1 (ASC) / $sort[field]=-1 (DESC) |
| Select | $select[0]=col1&$select[1]=col2 |
| Pagination | $limit=N&$skip=M (offset-based, skip = (page − 1) × limit) |
The dollar-prefixed system params ($limit, $skip, $sort, $select) are fixed by the Feathers adapter-commons query parser and ignore request key overrides — the dollar prefix is how Feathers tells system params apart from filter fields.
Pagination is offset-based on the wire, but your state stays page-based: setPage(3) with setLimit(10) emits $limit=10&$skip=20.
Operator filters
Section titled “Operator filters”FilterOperatorEnum translates to Feathers’ $operator syntax:
import { FilterOperatorEnum } from 'ng-qubee';
qb.addFilterOperator('age', FilterOperatorEnum.GTE, 18); // age[$gte]=18qb.addFilterOperator('age', FilterOperatorEnum.EQ, 18); // age=18qb.addFilterOperator('id', FilterOperatorEnum.IN, 1, 2, 3); // id[$in][0]=1&id[$in][1]=2&id[$in][2]=3qb.addFilterOperator('status', FilterOperatorEnum.NOT, 'draft'); // status[$ne]=draftqb.addFilterOperator('status', FilterOperatorEnum.NOT, 'a', 'b'); // status[$nin][0]=a&status[$nin][1]=bqb.addFilterOperator('price', FilterOperatorEnum.BTW, 10, 50); // price[$gte]=10&price[$lte]=50Translation table
Section titled “Translation table”FilterOperatorEnum |
Feathers expression |
|---|---|
EQ |
bare field=value (no operator wrapper) |
GT / GTE / LT / LTE |
[$gt] / [$gte] / [$lt] / [$lte] |
IN |
[$in][N]= (one indexed param per value) |
BTW |
[$gte] + [$lte] pair on the same field (arity-checked) |
NOT (single) |
[$ne] |
NOT (multi) |
[$nin][N]= (one indexed param per value) |
CONTAINS / ILIKE / SW |
unsupported — LIKE-style matching is adapter-specific ($like, $iLike, $regex), not part of the common syntax; throws UnsupportedFilterOperatorError |
NULL |
unsupported — no null-check operator on the wire; throws UnsupportedFilterOperatorError |
FTS / PHFTS / PLFTS / WFTS |
unsupported — throws UnsupportedFilterOperatorError |
Feathers’ $or top-level operator has no fluent-method counterpart and is not exposed.
Value shape rules
Section titled “Value shape rules”BTW requires exactly 2 values (min, max) — enforced at call time with InvalidFilterOperatorValueError. Other operators leave shape validation to the server.
Feature matrix
Section titled “Feature matrix”| Method | Supported? | Notes |
|---|---|---|
addFilter / deleteFilters |
✓ | Bare exact match (single) or [$in] (multi) |
addFilterOperator / deleteOperatorFilters |
✓ | See translation table above |
addSort / deleteSorts |
✓ | $sort[field]=1|-1 map, multi-field |
setLimit / setPage |
✓ | $limit + derived $skip |
addSelect / deleteSelect |
✓ | $select[N]= indexed array |
addFields / deleteFields / deleteFieldsByModel |
✗ | No per-model field selection |
addIncludes / deleteIncludes |
✗ | Relation loading is resolver-side in Feathers, no query param |
addEmbedded / deleteEmbedded |
✗ | Throws UnsupportedEmbeddedError |
setSearch / deleteSearch |
✗ | No global search param in the common syntax |
Response shape
Section titled “Response shape”Feathers database adapters return an offset-based envelope when pagination is enabled on the service:
{ "total": 48, "limit": 10, "skip": 10, "data": [{ "id": 11, "text": "Hello" }]}FeathersResponseStrategy maps total → total and limit → perPage, then derives position arithmetically — the envelope carries no page number and no navigation URLs:
pageis⌊skip ÷ limit⌋ + 1(a zero or missinglimit— e.g. a$limit=0count-only query — falls back to page 1).lastPageisceil(total ÷ limit).from/toare 1-indexed offsets fromskipand the item count of the current page (from = skip + 1,to = skip + data.length); both stayundefinedon an empty page.
The firstPageUrl/prevPageUrl/nextPageUrl/lastPageUrl slots on PaginatedCollection stay undefined.
The data / total / limit key paths are configurable (the skip key is fixed by the envelope):
provideNgQubee({ driver: DriverEnum.FEATHERS, response: { data: 'results', perPage: 'pageSize', total: 'count' }});Defaults are encoded in FeathersResponseOptions.