Skip to content

🔎 💫 Transfrom automatically Express.js req.query into your favourite query tool

License

Notifications You must be signed in to change notification settings

Tool-Kid/express-query-adapter

Repository files navigation

Express Query Adapter logo

Express Query Adapter

Easily transform an Express req.query into your favourite query tool






Contributing · License

Installation

npm install @tool-kid/express-query-adapter

How it works?

Usage

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);

Adapters

TypeORM

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
}

Different ways of retrieve data

GET, POST method by url query string

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 method by body

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
});

Available Lookups

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

Options

Pagination

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

Ordering

Option Default Behaviour Example
order - Order for fields:
+: Ascendant
-: Descendant
order=+foo,-name,+surname

Selection

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

Profile

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

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

About

🔎 💫 Transfrom automatically Express.js req.query into your favourite query tool

Resources

License

Stars

Watchers

Forks

Packages

No packages published