Product
Introducing License Enforcement in Socket
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
@nodebrick/nodebrick-api
Advanced tools
__
$ npm install --save @nodebrick/nodebrick-api
The nodebrick-api has a middleware that will parse the options
query parameter.
The options query parameter can have none or all the following objects
{fieds:{}, filters:{}, sort{}}
How each string is defined for fields
, filters
and sort
is covered further down.
The parsed options (options
of type nodebrick-core/src/models/IResourceOptions
) will be available in the controller using the @Options
decorator.
It will also be available in the application context under IResourceOptionContext
, i.e applicationContext.get(IResourceOptionsContext)
Please read the nodebrick-core context documentation for more information on contexts.
All options use the following way of selecting objects
Use a comma-separated list to select multiple fields.
Use a/b
to select a property b
that is nested within object a
; use a/b/c
to select a property c
nested within b
nested within a
.
Use a sub-selector to request a set of specific sub-fields of arrays or objects by placing expressions in parentheses ( )
.
For example: {fields:{items(id,author/email)}}
returns only the item ID and author's email for each element in the items array.
You can also specify a single sub-field, where {fields:{items(id)}}
is equivalent to {fields:{items/id}}
.
Use a comma-separated list to select multiple fields.
For example:
{sort:{email:DESC)}}
will sort on email field, DESC{sort:{contact/email:DESC)}}
will sort on the contact.email field, DESCIOptionSort
, parsed version of the sort option will be available in the application context under IOptionSortContext
, i.e applicationContext.get(IOptionSortContext)
In the controller you will also be able to access the filters via the options.sort
, options being the object decorated with @Options
in the method parameters.
Example
?options={sort:{name:DESC}}
The following fields object will be available
{
"createdAt": "2019-01-24T21:38:55.011Z",
"updatedAt": "2019-01-24T21:38:55.011Z",
"deletedAt": null,
"uuid": "b989ad79-c0ab-47d8-ac1a-745c8ae52f61",
"name": "wellington",
"population": 418500,
"date": "2019-01-24T21:38:55.011Z"
},
{
"createdAt": "2019-02-01T00:55:19.285Z",
"updatedAt": "2019-02-01T00:55:19.285Z",
"deletedAt": null,
"uuid": "eda0172b-a1b4-40b2-a3bd-d3ca684317aa",
"name": "tauranga",
"population": 141600,
"date": "2019-02-01T00:55:19.285Z"
},
{
"createdAt": "2019-02-01T00:55:19.051Z",
"updatedAt": "2019-02-01T00:55:19.051Z",
"deletedAt": null,
"uuid": "8708664d-211b-48c6-bae4-016ddaa96217",
"name": "tauranga",
"population": 141600,
"date": "2019-02-01T00:55:19.051Z"
},
{
"createdAt": "2019-02-01T00:55:18.803Z",
"updatedAt": "2019-02-01T00:55:18.803Z",
"deletedAt": null,
"uuid": "e7d1af07-3016-4903-bc19-6ef406a58428",
"name": "tauranga",
"population": 141600,
"date": "2019-02-01T00:55:18.803Z"
},
{
"createdAt": "2019-02-01T00:55:17.679Z",
"updatedAt": "2019-02-01T00:55:17.679Z",
"deletedAt": null,
"uuid": "11938bdd-1687-4ea1-a763-7a4333e90117",
"name": "tauranga",
"population": 141600,
"date": "2019-02-01T00:55:17.679Z"
}
...
Use a comma-separated list to select multiple fields.
For example:
{fields:{items}}
returns only the item object/array/property.{fields:{items(id,author/email)}}
returns only the item ID and author's email for each element in the items array.IOptionFields
, parsed version of the fields option will be available in the application context under IOptionFieldsContext
, i.e applicationContext.get(IOptionFieldsContext)
Example
?options={fields:{author,library(name/common,address(city,country/code)),price}}
The following fields object will be available
{
author: true,
library: {
name: {
common: true
},
address: {
city: true,
country: {
code: true
}
}
},
price: true
}
This object is used by the interceptor to trim down the resource sent back.
If a specified field doesn't exists on the resource it will error.
Use a comma-separated list to select multiple filters.
A filter is structured like property:operator_value
for one value or property:operator_value1_value2...
if multiple values are requires by the operator
You can see the list of all available operator on the nodebrick-core documentation
For example:
{filters:{email:$like_%xavier.martin%)}}
will ask to return all object having email like %xavier.martin%
{filters:{contactemail:$like_%xavier.martin%)}}
will ask to return all object having contact.email like %xavier.martin%
OptionFilters
, parsed version of the filter option will be available in the application context under OptionFiltersContext
, i.e applicationContext.get(OptionFiltersContext)
In the controller you will also be able to access the filters via the options.filters
, options being the object decorated with @Options
in the method parameters.
The filters object has keys as the properties you filtered on. The value looking like this:
property: string,
value: [string]|[string,string],
operator: FilterOperatorsEnum,
operatorSQL: [string]|[string, string]
Example
?options={filters:{author:$like_stephen king,book:$nilike_it,date:$between_1995-01-01_2018-12-12}}
The following filters object will be available:
{
author: {
property: "author",
value: [
"stephen king"
],
operator: "$like",
operatorSQL: [
"LIKE"
]
},
book: {
property: "book",
value: [
"it"
],
operator: "$nilike",
operatorSQL: [
"NOT ILIKE"
]
},
date: {
property: "date",
value: [
"1995-01-01",
"2018-12-12"
],
operator: "$between",
operatorSQL: [
"BETWEEN",
"AND"
]
}
}
Use this object to alter your query.
We have implemented two types of paginations, seek and offset.
Offset pagination requires the record you want to start from and a limit (number of records to return).
This is VERY inefficient. It requires the database to also work with on all the previous records.
This is somehow the default almost everywhere.
Seek (extension of keyset pagination, have a look) pagination where you give the ID to get result after or before. This also use the limit (number of item to return). This is efficient as the database will jump exactly to this record and the next number and work on those.
So the nodebrick-api has written those contexts, how can they be leveraged?
An example is the nodebrick-database as show here:
public async getManyWithQueryBuilder(): Promise<IModel[]>
{
// create the query builder
const query: SelectQueryBuilder<IModel> = this.manager.createQueryBuilder(IModel, "mod_a");
// ask the service the count value
// this is executed only if the client requested a count, see later
await this._dbService.filter(query);
await this._dbService.sort(query);
await this._dbService.paginate(query);
await this._dbService.count(query);
// or you can do
await this._dbService.applyOptions(query);
return query.getMany();
}
and that's it.
The count
method will count records, if requested by the client
The paginate
method will paginate the result if requested by the client
Add the following query parameters:
A count property will be added to the response with the following structure
{
"do_count": <boolean>,
"count": <integer>
}
Example
Request:
/resource?count=true
Response:
{
"data": {},
"count": {
"do_count": true,
"count": 40
}
}
Add the following query parameters:
Example
Request:
/resource?limit=5&start=5
Response:
{
"data": {},
"pagination": {
"type": "offset",
"limit": 5,
"start": 5,
"prev_url": "/resource?limit=5&start=0",
"self_url": "/resource?limit=5&start=5",
"next_url": "/resource?limit=5&start=10"
}
}
Add the following query parameters:
Example
Request:
/resource?limit=5&before=c8dae5da-0b64-4b55-ab56-95f59b9eb8b2
Response:
{
"data": {},
"pagination": {
"type": "seek",
"limit": 5,
"after": null,
"before": "c8dae5da-0b64-4b55-ab56-95f59b9eb8b2",
"self": "/nodebrick-api/options?limit=5&before=c8dae5da-0b64-4b55-ab56-95f59b9eb8b2&options=%7Bfields%3A%7Bauthor,library(name%2Fcommon,address(city,country%2Fcode)),price%7D,filters%3A%7Bauthor%3A%24like_stephen%20king,book%3A%24nilike_it,date%3A%24between_1995-01-01_2018-12-12%7D%7D",
"prev": "/nodebrick-api/options?limit=5&before=undefined&options=%7Bfields%3A%7Bauthor,library(name%2Fcommon,address(city,country%2Fcode)),price%7D,filters%3A%7Bauthor%3A%24like_stephen%20king,book%3A%24nilike_it,date%3A%24between_1995-01-01_2018-12-12%7D%7D"
}
}
FAQs
Nodebrick API module, providing express server
The npm package @nodebrick/nodebrick-api receives a total of 4 weekly downloads. As such, @nodebrick/nodebrick-api popularity was classified as not popular.
We found that @nodebrick/nodebrick-api demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
Product
We're launching a new set of license analysis and compliance features for analyzing, managing, and complying with licenses across a range of supported languages and ecosystems.
Product
We're excited to introduce Socket Optimize, a powerful CLI command to secure open source dependencies with tested, optimized package overrides.