An open API service indexing awesome lists of open source software.

https://github.com/guichaguri/crud-query-parser

Parses queries from HTTP requests and adapts them to database queries
https://github.com/guichaguri/crud-query-parser

crud-api crud-requests dynamodb express mongodb mongoose nextjs sequelize typeorm

Last synced: about 1 year ago
JSON representation

Parses queries from HTTP requests and adapts them to database queries

Awesome Lists containing this project

README

          

# crud-query-parser

[![NPM](https://img.shields.io/npm/v/crud-query-parser)](https://www.npmjs.com/package/crud-query-parser) [![Coverage](https://img.shields.io/codecov/c/github/Guichaguri/crud-query-parser?token=KFJIJ220HD)](https://codecov.io/github/Guichaguri/crud-query-parser)

This library parses query parameters from HTTP requests and converts them to database queries, allowing advanced filtering, column selection, pagination and relation joining.

## Features

- Modular architecture, can be extended as needed
- Flexible request manipulation and filtering
- Supports the `@nestjsx/crud` query parameter syntax
- [TypeORM support](./docs/adapters/typeorm.md)
- [Sequelize support](./docs/adapters/sequelize.md)
- [MongoDB and Mongoose support](./docs/adapters/mongodb.md)
- [DynamoDB support](./docs/adapters/dynamodb.md)
- [JS arrays support](./docs/adapters/array.md)
- Framework-agnostic
- Supports [NestJS](./docs/frameworks/nestjs.md), [NextJS](./docs/frameworks/nextjs.md), [Express](./docs/frameworks/express.md), [Fastify](./docs/frameworks/fastify.md), [h3](./docs/frameworks/h3.md), [tinyhttp](./docs/frameworks/tinyhttp.md), [http package](./docs/frameworks/nodejs-http.md) and many more

## Install

```sh
npm install crud-query-parser
```

## Usage

```mermaid
flowchart LR
A(RequestParser) --> B(Filters) --> C(QueryAdapter)
```

You have to pick a request parser and a query adapter.

```ts
const parser = new CrudRequestParser();
const adapter = new TypeOrmQueryAdapter();
const userRepository = AppDataSource.getRepository(UserEntity); // TypeORM repository

// ...

// The request query object
// This object will likely come from the HTTP request
const requestQuery = { ... };

// Parses the query into a CrudRequest object
let crudRequest = parser.parse(requestQuery);

// Apply filters
// crudRequest = filterRelations(crudRequest, ['posts']);
// crudRequest = ensureLimit(crudRequest, 25, 100);

// Using the query adapter, you can run the query through your ORM by using the CrudRequest
const result = await adapter.getMany(userRepository.createQueryBuilder(), crudRequest); // GetManyResult

// The result object has properties like data, page, total
console.log(result);
```

## Request parsers

### CRUD Request

The CRUD Request parser is an implementation of the `@nestjsx/crud` [query params format](https://github.com/nestjsx/crud/wiki/Requests#query-params).

```ts
import { CrudRequestParser } from 'crud-query-parser/parsers/crud';

const parser = new CrudRequestParser();

// Then, you have to pass a query string object to it
// const crudRequest = parser.parse(request.query);
```

Read more about the [CRUD Request parser](./docs/parsers/crud.md).

## Database adapters

### TypeORM

This adapter works with TypeORM 0.3.x and 0.2.x

```ts
import { TypeOrmQueryAdapter } from 'crud-query-parser/adapters/typeorm';

const adapter = new TypeOrmQueryAdapter();

// Then, you can pass a query builder to it:
// const result = await adapter.getMany(repository.createQueryBuilder(), crudRequest);
```

Read more about the [TypeORM adapter](./docs/adapters/typeorm.md).

### Sequelize

This adapter works with Sequelize 6

```ts
import { SequelizeQueryAdapter } from 'crud-query-parser/adapters/sequelize';

const adapter = new SequelizeQueryAdapter();

// Then, you can pass a FindOptions to it:
// const result = await adapter.getMany({}, crudRequest);
```

Read more about the [Sequelize adapter](./docs/adapters/sequelize.md).

### DynamoDB

This adapter requires [@aws-sdk/client-dynamodb](https://www.npmjs.com/package/@aws-sdk/client-dynamodb) and [@aws-sdk/util-dynamodb](https://www.npmjs.com/package/@aws-sdk/util-dynamodb) 3.x.x

```ts
import { DynamoDBQueryAdapter } from 'crud-query-parser/adapters/dynamodb';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

const adapter = new DynamoDBQueryAdapter({
client: new DynamoDBClient(),
tableName: 'posts',
partitionKey: 'id',
});

// Then, you can pass a partial Query/Scan input to it:
// const result = await adapter.getMany({}, crudRequest);
```

Read more about the [DynamoDB adapter](./docs/adapters/dynamodb.md).

### MongoDB

```ts
import { MongoDBQueryAdapter } from 'crud-query-parser/adapters/mongodb';

const adapter = new MongoDBQueryAdapter();

// Then, you can pass a collection to it:
// const result = await adapter.getMany(collection, crudRequest);
```

Read more about the [MongoDB adapter](./docs/adapters/mongodb.md).

### Mongoose

```ts
import { MongooseQueryAdapter } from 'crud-query-parser/adapters/mongodb';

const adapter = new MongooseQueryAdapter();

// Then, you can pass a Query to it:
// const result = await adapter.getMany(Model.find(), crudRequest);
```

Read more about the [Mongoose adapter](./docs/adapters/mongodb.md).

### Array

This adapter can filter, sort and map plain JS arrays.

```ts
import { ArrayQueryAdapter } from 'crud-query-parser/adapters/array';

const adapter = new ArrayQueryAdapter();

// Then, you can pass an array of entities to it:
// const result = await adapter.getMany([], crudRequest);
```

Read more about the [array adapter](./docs/adapters/array.md).

## Frameworks

crud-query-parser is framework-agnostic. You can pass any query parameters object to the parser and it should work out-of-the-box.
We have a few examples for the frameworks listed below:

- [NestJS](./docs/frameworks/nestjs.md)
- [NextJS](./docs/frameworks/nextjs.md)
- [Express](./docs/frameworks/express.md)
- [Fastify](./docs/frameworks/fastify.md)
- [h3](./docs/frameworks/h3.md)
- [tinyhttp](./docs/frameworks/tinyhttp.md)
- [Node.js http](./docs/frameworks/nodejs-http.md)

We also have special integrations to improve DX:

### NestJS Integration

The NestJS Integration has decorators that automatically parses the request. It also has built-in OpenAPI support.

```ts
import { Crud, ParseCrudRequest } from 'crud-query-parser/helpers/nestjs';
import { CrudRequestParser } from 'crud-query-parser/parsers/crud';

@Controller('users')
export class UserController {

@Get()
@Crud(CrudRequestParser) // <- You specify which parser to use
public async getMany(@ParseCrudRequest() crudRequest: CrudRequest) { // <- The request query will be automatically parsed
// ...
}

}
```

Read more about the [NestJS Integration](docs/frameworks/nestjs.md).

### Express Integration

The Express Integration has a middleware that automatically parses and memoizes the request.

```ts
import { crud } from 'crud-query-parser/helpers/express';
import { CrudRequestParser } from 'crud-query-parser/parsers/crud';

app.use(crud(CrudRequestParser)); // <- You specify which parser to use

app.get('/users', (req, res) => {
const crudRequest = req.getCrudRequest(); // <- The request will be automatically parsed and memoized

// ...
});
```

Read more about the [Express Integration](docs/frameworks/express.md).

## Filters

You may need to filter what the user can or cannot query. You are free to modify the `CrudRequest` object however you like.

There are a few filters provided by the library, which are listed below.

### Enforce a "where" condition

This filter will add the condition on top of all other where conditions

```ts
import { ensureCondition, ensureEqCondition } from 'crud-query-parser/filters';

// ...

crudRequest = ensureCondition(crudRequest, {
field: ['isActive'],
operator: CrudRequestWhereOperator.EQ,
value: true,
});

// Alternatively, a shorthand for equals conditions:
crudRequest = ensureEqCondition(crudRequest, {
isActive: true,
});
```

### Ensure page limit

This filter will ensure that the requested limit does not go above the maximum.
It also sets a default value whenever the limit is omitted.

```ts
import { ensureLimit } from 'crud-query-parser/filters';

// ...

const defaultLimit = 25;
const maxLimit = 100;

crudRequest = ensureLimit(crudRequest, defaultLimit, maxLimit);
```

### Filter property access

This filter removes any property from the request that is not in the allowlist.
It removes unallowed properties from the select fields, where conditions, relations and sorting.

```ts
import { filterProperties } from 'crud-query-parser/filters';

// ...

crudRequest = filterProperties(crudRequest, [
'id',
'name',
'posts',
'posts.id',
'posts.name',
]);
```

### Filter relations

This filter removes any relation from the request that is not in the allowlist.
It's the same as the `filterProperties` but only filters relations.

```ts
import { filterRelations } from 'crud-query-parser/filters';

// ...

crudRequest = filterRelations(crudRequest, ['posts']);
```