OData Query Builder
OData query builder that uses chain sytax.
Table of Content
Install
yarn add @vlad160/odata-query-builder
or
npm i @vlad160/odata-query-builder --save
Usage
Use type helpers to build your query expression and call toString()
NOTE: Query is not encoded by default. Use toString({ encode: true })
for query encoding
Only OData4 provider is implemented for now. PR's with OData3 are accepted :)
Filter
You can use both ODataFilter
or ODataQuery
to build filter query.
Default logical operator is AND. You can change it by passing LogicalOperator
directly to the ODataFilter
constructor. See below for more examples
Simple filter
const query = new OData4Query();
query.filter(f => f.eq('Name', 'John')
.gt('Age', 5)
.toString()
)
Output
$filter=(Name eq 'John') and (Age gt 5)
Filter with fuctions
const query = new OData4Query();
query.filter(f => f.eq(x => x.toLower('Name'), 'John')
.gt(x => x.round('Age'), 5)
.toString()
)
Output
$filter=(tolower(Name) eq 'John') and (round(Age) gt 5)
Piping
const query = new OData4Query();
query.filter(f => f.pipe(
eq(x => x.toLower('Name'), 'John'),
gt(x => x.round('Age'), 5)
))
Complex filtering with logical operator changing
const filter = new OData4Filter();
filter
.pipe(eq(x => x.toUpper('Surname'), 'SNOW'), gt('Age', 25))
.eq('Name', 'John')
.or(x => x.gt(x => x.length('Name'), 15))
.not(x => x.eq('Name', 'Tition')
.lt('Age', 50), LogicalOperator.OR);
Output
((toupper(Surname) eq 'SNOW') and (Age gt 25) and (Name eq 'John')) or (length(Name) gt 15) not ((Name eq 'Tition') or (Age lt 50))
Count
const query = new OData4Query();
query
.count()
Output
$count=true
Skip/Top
const query = new OData4Query();
query
.skip(5)
.top(10)
.toString()
Output
$top=10&$skip=5
Select
const query = new OData4Query();
query
.select('Name', 'Surname')
.toString()
Output
$select=Name,Surname
Search
const query = new OData4Query();
query
.select('Some Query')
.toString()
Output
$select=Some Query
OrderBy
Keep in mind that orderBy
returns OrderedQuery
and only skip
, top
and thenBy
operators could be applied
const query = new OData4Query();
query
.orderBy('Name', Order.ASC)
.thenBy('Surname', Order.DESC)
.skip(5)
.top(228)
.toString()
Output
$orderBy=Name asc,Surname desc&$top=228&$skip=5
Expand
Simple multiple expand
const query = new OData4Query();
query
.expand(['Result', 'Items'])
.toString()
Output
$expand=Result,Items
Expand nested property
const query = new OData4Query();
query
.expand('Result/Items')
.toString()
Output
$expand=Result($expand=Items)
Expand with query
const query = new OData4Query();
query
.expand('Result', q =>
q.select('Items')
.filter(f => f.gt('Price', 5))
.top(5))
.toString()
Output
$expand=Result($select=Items;$top=5;$filter=Price gt 5)
Object based expand
const query = new OData4Query();
query
.expand({
'Result': {
top: 5
}, 'Items': {}
})
.toString()
Output
$expand=Result($top=5),Items
Piping
const query = new OData4Query();
query
.pipe(select('Name'),
expand('Result'),
skip(5),
top(10))
.toString()
Output
$expand=Result&$select=Name&$top=10&$skip=5