nest_crud_request 1.3.0
nest_crud_request: ^1.3.0 copied to clipboard
Framework-agnostic query builder for @ackplus/nest-crud REST APIs — build filters, relations, aggregates, ordering and pagination for Flutter and Dart.
nest_crud_request (Dart / Flutter) #
Part of the nest-crud family — one server + two query-builder clients, released together at the same version:
Package Get it Docs @ackplus/nest-crud— NestJS + TypeORM server📦 npm Getting started @ackplus/nest-crud-request— JS / TS query builder📦 npm Client guide nest_crud_request— Dart / Flutter query builder · this package📦 pub.dev Flutter guide 📖 Full documentation: https://ack-solutions.github.io/nest-crud/ · 🧩 All packages · 💻 GitHub
Framework-agnostic query builder for @ackplus/nest-crud
REST APIs — the Dart twin of the JS @ackplus/nest-crud-request.
Build filters, relations, aggregates, ordering and pagination with a fluent API,
then drop the result straight into dio / http. It produces the exact same
query strings as the JS client, so it talks to your existing API with no server
changes. Pure Dart, zero runtime dependencies.
This package builds the request query parameters only (mirroring the JS request builder). It does not wrap HTTP — use any client you like.
Install #
dependencies:
nest_crud_request: ^1.1.42
Quick start #
import 'package:nest_crud_request/nest_crud_request.dart';
final params = (QueryBuilder()
..where('status', 'active') // equality
..whereOp('age', WhereOperator.gte, 18) // operator
..addRelation('posts', select: ['id', 'title']) // join + columns
..addOrder('createdAt', OrderDirection.desc)
..setTake(20)
..setSkip(0))
.toQueryParameters(); // Map<String,String>
// with dio:
final res = await dio.get('/users', queryParameters: params);
// → GET /users?where={"status":{"$eq":"active"},...}&take=20&skip=0
Where conditions #
Four forms, each available as where / andWhere / orWhere:
qb.where('status', 'active'); // field = value
qb.whereOp('age', WhereOperator.gte, 18); // field, operator, value
qb.whereRaw({'role': {r'$in': ['admin', 'editor']}}); // raw object
qb.whereGroup((g) => g // nested group: (a OR b)
..orWhere('role', 'admin')
..orWhere('role', 'owner'));
where/andWherecombine with AND;orWherewith OR.- Value-less operators:
qb.whereOp('deletedAt', WhereOperator.isNull, true). - Relation existence:
qb.whereOp('posts', WhereOperator.exists, true).
Operators #
| Dart | Token | Meaning |
|---|---|---|
eq ne ieq |
$eq $ne $ieq |
equal / not equal / case-insensitive equal |
gt gte lt lte |
$gt $gte $lt $lte |
comparison |
inList notIn |
$in $notIn |
in / not in a list |
inL notinL |
$inL $notinL |
case-insensitive in / not in |
like notLike iLike notIlike |
$like … |
SQL LIKE (and case-insensitive) |
startsWith endsWith iStartsWith iEndsWith |
$startsWith … |
prefix / suffix |
between notBetween |
$between $notBetween |
range [start, end] |
isNull isNotNull |
$isNull $isNotNull |
null checks |
isTrue isFalse |
$isTrue $isFalse |
boolean checks |
contArr intersectsArr |
$contArr $intersectsArr |
Postgres array contains / overlaps |
exists notExists |
$exists $notExists |
relation has / has no rows |
Logical grouping: WhereLogicalOperator.and / .or.
Relations #
qb.addRelation('profile'); // join, all columns
qb.addRelation('posts', select: ['id', 'title']); // pick columns
qb.addRelation('posts', where: {'status': 'published'}, joinType: 'inner');
Order, pagination, soft-delete #
qb..addOrder('createdAt', OrderDirection.desc)
..addOrder('name', OrderDirection.asc)
..setTake(20)..setSkip(40)
..setWithDeleted(true) // include soft-deleted
..setOnlyDeleted(true); // only soft-deleted
Aggregates & HAVING #
Per-row aggregates over a relation, filtered and sorted by the alias:
qb..addAggregate(fn: AggregateFn.count, field: 'posts.id', as: 'postCount')
..addAggregate(fn: AggregateFn.sum, field: 'posts.likes', as: 'totalLikes',
where: {'status': 'published'}) // per-aggregate filter
..havingOp('postCount', WhereOperator.gt, 5)
..addOrder('postCount', OrderDirection.desc);
Output #
qb.toQueryParameters(); // Map<String,String> — HTTP query params (recommended)
qb.toObject(); // Map<String,dynamic> — complex fields JSON-stringified
qb.toObject(nested: true); // keep complex fields as native maps/lists
qb.toJson(); // one JSON string of the nested form
Empty sections are omitted. Custom keys: qb.set('search', 'alice').
Keeping in sync with the JS client #
The operator tokens and serialization mirror @ackplus/nest-crud-request exactly
and are pinned by test/operators_test.dart. Both clients are released together at
the same version, so a query built in Flutter behaves identically to one built in JS.
License #
MIT © Ackplus