Easily transform an Express req.query into your favourite query tool
Contributing
·
License
npm install @tool-kid/express-query-adapter
Use getQueryBuilder
exported from package and pass your req.query
as an argument:
import { getQueryBuilder } from '@tool-kid/express-query-adapter';
const builder = await getQueryBuilder({ adapter: 'typeorm' });
const builtQuery = builder.build(req.query);
// Now your query is built, pass it to your favourite tool
const results = await fooRepository.find(builtQuery);
Given the following url query string:
foo/?name__contains=foo&role__in=admin,common&age__gte=18&page=3&limit=10
It will be transformed into:
{
where: {
foo: Like('%foo%'),
role: In(['admin', 'common']),
age: MoreThanOrEqual(18)
},
skip: 20,
take: 10
}
GET foo/?name__contains=foo&role__in=admin,common&age__gte=18&page=3&limit=10
POST foo/?name__contains=foo&role__in=admin,common&age__gte=18&page=3&limit=10
app.get('/foo', (req, res) => {
const qb = await getQueryBuilder({ adapter: 'typeorm' });
const built = qb.build(req.query); // => Parsed into req.query
});
POST foo/, body: {
"name__contains": "foo",
"role__in": "admin,common",
"age__gte": 18,
"page": 3,
"limit": 10
}
app.post('/foo', (req, res) => {
const qb = await getQueryBuilder({ adapter: 'typeorm' });
const built = qb.build(req.query); // => Parsed into req.body
});
Lookup | Behaviour | Example |
---|---|---|
(none) | Return entries that match with value | foo=raul |
contains | Return entries that contains value | foo__contains=lopez |
startswith | Return entries that starts with value | foo__startswith=r |
endswith | Return entries that ends with value | foo__endswith=dev |
icontains | Return entries that contains value and ignoring case | foo__icontains=Lopez |
istartswith | Return entries that starts with value and ignoring case | foo__istartswith=R |
iendswith | Return entries that ends with value and ignoring case | foo__iendswith=Dev |
isnull | Return entries with null value | foo__isnull |
lt | Return entries with value less than or equal to provided | foo__lt=18 |
lte | Return entries with value less than provided | foo__lte=18 |
gt | Returns entries with value greater than provided | foo__gt=18 |
gte | Return entries with value greater than or equal to provided | foo__gte=18 |
in | Return entries that match with values in list | foo__in=admin,common |
between | Return entries in range (numeric, dates) | foo__between=1,27 |
Notice: you can use negative logic prefixing lookup with __not
.
Example:
foo__not__contains=value
Option | Default | Behaviour | Example |
---|---|---|---|
pagination | true | If true, paginate results. If false, disable pagination | pagination=false |
page | 1 | Return entries for page page |
page=2 |
limit | 25 | Return entries for page page paginated by size limit |
limit=15 |
Option | Default | Behaviour | Example |
---|---|---|---|
order | - | Order for fields:+ : Ascendant - : Descendant |
order=+foo,-name,+surname |
Option | Default | Behaviour | Example |
---|---|---|---|
select | - | Fields to select as response. If no provided, it select all fields. | select=name,surname,foo.nested |
with | - | Entity relations to attach to query | with=posts,comments |
If you need to disable some capabilities, you can do using shortcuts to enable|disable
by default or provide a custom Profile.
A Profile describe capabilities that can be used by clients & its behaviour.
const qb = getQueryBuilder({ adapter: 'typeorm', profile: 'enabled' | 'disabled' | ConfigProgile });
const builtQuery = builder.build(req.query);
ConfigProfile
object looks like:
const customProfile: ConfigProfile = {
options: {
pagination: {
status: 'enabled',
paginate: true,
itemsPerPage: 25,
},
ordering: {
status: 'enabled',
},
relations: {
status: 'enabled',
},
select: {
status: 'enabled',
},
},
policy: 'skip',
};
Field | Default | Behaviour | Type |
---|---|---|---|
options | 'enabled' | Profile options | ProfileOptions |
policy | 'skip' | Policy to apply in cases client try use disabled options |
FindPolicyType |