CRUD-Gen REST Usage
GraphQL is still the richest generated surface, but CRUD-Gen includes REST helpers for generated CRUD controllers, pagination, sorting, filtering, and Swagger-friendly responses.
DTOs and params
- Use
crudGenRestParamsFactory(entityModel?, defaultValue?)to get a query DTO withstartRow/endRow,sorting, andfilters. -
sortingandfiltersare accepted as JSON-encoded query parameters by generated REST controllers. -
crudGenRestParamsNoPaginationFactorybuilds a DTO without pagination when you only need sorting. -
CGRestQueryArgs/CGQueryArgsNoPaginationcombine Nest@Queryparams, optional extra args, and mapping intoCrudGenFindManyOptions. -
PageDataandPaginatedResultDtoshape paginated responses;ApiOkResponsePaginated(dto)decorates Swagger responses withnodes+pageData.
Mapping requests to find options
-
mapCrudGenRestParams/CrudGenRestArgsFactoryreuse the same mapping as GraphQL (mapCrudGenParam) to turn query params into TypeORM-friendlyCrudGenFindManyOptions. -
startRowandendRoware parsed as numbers from HTTP query strings. -
sortingandfiltersare parsed from JSON when passed as strings. Malformed JSON returns a400 Bad Request. - Extra args behave like GraphQL: declare them in
extraArgsand they are exposed as query params unlesshidden. - For generated REST controllers, flat query params such as
?projectId=...or?guid=...are now mapped as simple equality filters on top of the normal pagination/sorting mapping. This keeps common CRUD list endpoints usable without inventing bespoke controller methods for every resource.
Example structured REST query:
GET /users?sorting=[{"colId":"firstName","sort":"ASC"}]&filters={"expressions":[{"text":{"field":"firstName","type":"contains","filter":"Alice","filterType":"text"}}]}
When building URLs manually, JSON values must be URL-encoded by the client.
supertest and most HTTP clients do this automatically when using a query
object.
Controllers
- Apply
CGQueryArgsto controller methods to receive mappedCrudGenFindManyOptions. - Pair with your service (e.g., a
GenericServicecreated viaCrudGenDependencyFactory) and returnPaginatedResultDto. - Swagger: decorate with
ApiOkResponsePaginated(MyDto)to document the paginated shape. - If you want a ready-made REST controller, use:
crudRestControllerFactory({ entityModel, dto?, path?, decorators?, query?, idField?, readonly?, mutations? })- register the returned class inside your module
controllers. - By default it wires full CRUD using
GenericService. The REST:idparameter is mapped to the entity’s single TypeORM primary column when it can be inferred; otherwise it falls back toid.-
GET /path→getEntityListExtended(with pagination helpers) -
GET /path/:id→getEntity -
POST /path→createEntity -
PUT /path/:id→updateEntity -
DELETE /path/:id→deleteEntity(returns{ deleted: boolean })
-
- Set
readonly: trueto expose only the read endpoints (GETlist +GET :id). - Use
mutations?: { create?: { disabled?: boolean; decorators?: IDecoratorType[] }; update?: { ... }; delete?: { ... } }to disable individual write endpoints or attach guards/interceptors specifically to them. - See
examples/skeleton/appfor the minimalCrudGenResourceFactorypath that composes REST, GraphQL, service, repository, and dataloader providers from one app-owned resource definition. - See
examples/omnikernel/appfor generated REST controllers over a reusable OmniKernel backend.
Notes
- REST supports simple equality filters via flat query params on generated controllers.
- Example:
GET /tasks?projectId=<uuid> - Example:
GET /projects?guid=<uuid>
- Example:
- REST supports structured JSON
filtersfor standard generated list endpoints. - Plain TypeORM fallback supports straightforward structured filters by normalizing CrudGen’s internal
filters/childExpressionsshape before callingfind/findAndCount. - Nested
ORfilters insideANDexpressions still require an extended repository/query override because TypeORM’s plain find options cannot represent every CrudGen expression tree. - Sorting uses entity field names; ensure your DTO exposes the same names you expect in the controller.
- If a resource uses a custom service provider, pass
serviceTokentocrudRestControllerFactory; otherwise the factory assumes the defaultgetServiceToken(entityModel)provider. - Alternative: you can expose REST via GraphQL Sofa (see
docs/api-creation.mdnote). Use Sofa if you want a fully automatic REST layer from GraphQL; use the controller factory if you need explicit paths, guards, or bespoke DTOs.