-
Notifications
You must be signed in to change notification settings - Fork 0
Requests
@nestjs-crud parses path and query parameters to give you rich RESTful APIs without hand-rolling boilerplate. @nestjs-crud/request is the package that does the parsing and validating.
The default param names:
-
fields,select: select which fields to return -
s: search conditions ($and,$or, all variations) -
filter: filter the GET result withANDconditions -
or: filter the GET result withORconditions -
join: include joined relational resources in the GET result (all or selected fields) -
sort: sort the GET result by one or more fields,ASCorDESC -
per_page,limit: cap the number of returned resources -
offset: skip a number of resources before returning the slice -
page: return a page oflimit-sized results -
cache: bypass cache (when caching is enabled) and read straight from the DB
You can rename any of these and pick different delimiters via global options.
Each param is described below using the default names.
Selects fields to return in the response body.
Syntax:
?fields=field1,field2,...
Example:
?fields=email,name
Adds a search condition as a JSON string. Combine $and, $or, and any condition you need. Send it URL-encoded, or use RequestQueryBuilder and let it encode for you.
Syntax:
?s={"name": "Michael"}
Examples:
- Search where
nameis eithernullOR equalsSuperman:
?s={"name": {"$or": {"$isnull": true, "$eq": "Superman"}}}
- Search where
isActiveistrueANDcreatedAtis not2008-10-01T17:04:32:
?s={"$and": [{"isActive": true}, {"createdAt": {"$ne": "2008-10-01T17:04:32"}}]}
which is the same as:
?s={"isActive": true, "createdAt": {"$ne": "2008-10-01T17:04:32"}}
- Search where
isActiveisfalseORupdatedAtis notnull:
?s={"$or": [{"isActive": false}, {"updatedAt": {"$notnull": true}}]}
The combinations compose freely.
-
$eq(=, equal) -
$ne(!=, not equal) -
$gt(>, greater than) -
$lt(<, less than) -
$gte(>=, greater than or equal) -
$lte(<=, less than or equal) -
$starts(LIKE val%, starts with) -
$ends(LIKE %val, ends with) -
$cont(LIKE %val%, contains) -
$excl(NOT LIKE %val%, does not contain) -
$in(IN, in range, accepts multiple values) -
$notin(NOT IN, not in range, accepts multiple values) -
$isnull(IS NULL, no value accepted) -
$notnull(IS NOT NULL, no value accepted) -
$between(BETWEEN, accepts two values) -
$eqL(LOWER(field) =, equal) -
$neL(LOWER(field) !=, not equal) -
$startsL(LIKE|ILIKE val%) -
$endsL(LIKE|ILIKE %val) -
$contL(LIKE|ILIKE %val%) -
$exclL(NOT LIKE|ILIKE %val%) -
$inL(LOWER(field) IN, accepts multiple values) -
$notinL(LOWER(field) NOT IN, accepts multiple values)
Adds a field-level condition (or several) to the request.
Syntax:
?filter=field||$condition||value
?join=relation&filter=relation.field||$condition||value
Nested filters require the relation to be joined first.
Examples:
?filter=name||$eq||batman
?filter=isVillain||$eq||false&filter=city||$eq||Arkham (multiple filters AND-combine)
?filter=shots||$in||12,26 (some conditions accept comma-separated values)
?filter=power||$isnull (some conditions take no value)
Adds OR conditions, using the same filter conditions.
Syntax:
?or=field||$condition||value
Rules and examples:
- One
or(withoutfilter) behaves like a single filter:
?or=name||$eq||batman
- Multiple
or(withoutfilter) combine asWHERE {or} OR {or} OR ...:
?or=name||$eq||batman&or=name||$eq||joker
- One
orplus onefiltercombines asWHERE {filter} OR {or}:
?filter=name||$eq||batman&or=name||$eq||joker
- Multiple of each: every
filterAND-combines, everyorAND-combines, then the two groups OR together:WHERE ({filter} AND {filter} AND ...) OR ({or} AND {or} AND ...)
?filter=type||$eq||hero&filter=status||$eq||alive&or=type||$eq||villain&or=status||$eq||dead
Sorts results by one or more fields.
Syntax:
?sort=field,ASC|DESC
Examples:
?sort=name,ASC
?sort=name,ASC&sort=id,DESC
Includes joined relational objects in the GET result (all or selected fields). Join as many relations as your CrudOptions allow.
Syntax:
?join=relation
?join=relation||field1,field2,...
?join=relation1||field11,field12,...&join=relation1.nested||field21,field22,...&join=...
Examples:
?join=profile
?join=profile||firstName,email
?join=profile||firstName,email&join=notifications||content&join=tasks
?join=relation1&join=relation1.nested&join=relation1.nested.deepnested
The primary key column always persists in relational objects. For nested relations, the parent level must be joined before the child level (as in the example above).
Caps the number of returned entities.
Syntax:
?limit=number
Example:
?limit=10
Skips the first N resources before returning the slice. Combine with limit for offset pagination, and with sort for deterministic order.
Syntax:
?offset=number
Example:
?offset=10
One-based page index. Combine with limit for predictable page sizes.
Syntax:
?page=number
Example:
?page=2
Bypass the cache (when caching is enabled) and read directly from the DB.
Usage:
?cache=0
@nestjs-crud/request is framework-agnostic and works on both backend and frontend. It is also used by @nestjs-crud/core inside CrudRequestInterceptor.
The RequestQueryBuilder class composes query strings and lets you customize param names and delimiters.
setOptions is a static method that lets you override the defaults (shown below):
import { RequestQueryBuilder } from '@nestjs-crud/request';
RequestQueryBuilder.setOptions({
delim: '||',
delimStr: ',',
paramNamesMap: {
fields: ['fields', 'select'],
search: 's',
filter: ['filter[]', 'filter'],
or: ['or[]', 'or'],
join: ['join[]', 'join'],
sort: ['sort[]', 'sort'],
limit: ['per_page', 'limit'],
offset: ['offset'],
page: ['page'],
cache: ['cache'],
},
});Compose a query string by chaining methods:
import { RequestQueryBuilder, CondOperator } from '@nestjs-crud/request';
const qb = RequestQueryBuilder.create();
// set search
qb.search({
$or: [
{
foo: { $notnull: true },
baz: 1,
},
{
bar: { $ne: 'test' },
},
],
});
// equivalent imperative form:
qb.setFilter({ field: 'foo', operator: CondOperator.NOT_NULL })
.setFilter({ field: 'baz', operator: '$eq', value: 1 })
.setOr({
field: 'bar',
operator: CondOperator.NOT_EQUALS,
value: 'test',
});
qb.select(['foo', 'bar'])
.setJoin({ field: 'company' })
.setJoin({ field: 'profile', select: ['name', 'email'] })
.sortBy({ field: 'bar', order: 'DESC' })
.setLimit(20)
.setPage(3)
.resetCache()
.query();Or pass everything to create:
const queryString = RequestQueryBuilder.create({
fields: ['name', 'email'],
search: { isActive: true },
join: [{ field: 'company' }],
sort: [{ field: 'id', order: 'DESC' }],
page: 1,
limit: 25,
resetCache: true,
}).query();