Skip to content

Configuration

@Crud(options)

OptionTypeDescription
entityclassRequired. The TypeORM entity.
pathstringURL path the controller mounts at (e.g. 'users'). Defaults to the entity name.
namestringOverride the name used for Swagger tags / operation ids.
routesobjectPer-route config — see below.
softDeletebooleanEnable soft-delete + the trash/restore routes.
maxPerPagenumberMax page size for list queries (default 5000). maxPageSize is a legacy alias.
selectstring[]Default columns to select when the request doesn't specify select.
hiddenFieldsstring[]Columns/relations to hide from the entire query surface (never selected, rejected in where/order/aggregates). Per-controller alternative to the @CrudHidden() decorator.
query.relationsstring[]Relations always joined for this controller.
messagesobjectOverride delete/restore/reorder response messages (i18n) — { deleted, noItemsToDelete, restored, reordered }.
validationValidationPipeOptions | falseOptions for the per-route ValidationPipe, or false to disable generated validation.
dto.create / dto.updateclassCustom request-body DTOs. When omitted, a DTO derived from the entity (minus id/timestamps) is used.
debugbooleanVerbose query logging (also toggled by the NEST_CRUD_DEBUG env var).

routes

Each route accepts { enabled, guards, interceptors, decorators } (or the boolean shorthand true / false). All routes are enabled by default; list a route with { enabled: false } to remove it.

ts
@Crud({
  entity: User,
  path: 'users',
  softDelete: true,
  routes: {
    create:  { enabled: true, guards: [JwtAuthGuard] },
    delete:  { enabled: true, guards: [JwtAuthGuard, AdminGuard] },
    findMany:{ enabled: true, interceptors: [CacheInterceptor] },
    reorder: false, // not an ordered entity → disable
  },
})

The route names are: findMany, findAll, counts, findOne, create, createMany, update, updateMany, delete, deleteMany, deleteFromTrash, deleteFromTrashMany, restore, restoreMany, reorder.

Generated routes

ActionMethod & pathReturns
findManyGET /{ items, total }
findAllGET /get/allT[]
countsGET /get/counts{ total, data? }
findOneGET /:idT
createPOST /T (201)
createManyPOST /bulkT[] (201)
updatePUT /:idT
updateManyPUT /bulkT[]
deleteDELETE /:id{ message }
deleteManyDELETE /delete/bulk?ids=…{ message }
reorderPUT /reorder
deleteFromTrash †DELETE /:id/trash{ success, message }
deleteFromTrashMany †DELETE /trash/bulk?ids=…{ success, message }
restore †PUT /:id/restore{ success, message }
restoreMany †PUT /restore/bulk{ success, message }

† only generated when softDelete: true.

Hiding sensitive fields

hiddenFields (and the @CrudHidden() entity decorator) remove columns or relations from the generated query surface entirely — they're never returned, and naming one in where / order / aggregates / relations returns 400, indistinguishable from an unknown field. This is a recently added security control; the full behaviour table and examples live in Querying → Hiding sensitive fields.

ts
@Crud({ entity: User, path: 'users', hiddenFields: ['passwordHash', 'auditLogs'] })
export class UserController {
  constructor(public service: UserService) {}
}

Response messages (i18n)

Override the messages returned by delete / restore / reorder — per controller via messages, or globally via CrudConfigService. Any omitted key falls back to the English default.

ts
@Crud({
  entity: User,
  path: 'users',
  messages: {
    deleted: 'Utilisateur supprimé',
    restored: 'Utilisateur restauré',
    reordered: 'Ordre mis à jour',
    noItemsToDelete: 'Aucun élément à supprimer',
  },
})

Global defaults — CrudConfigService / NestCrudModule.forRoot

Set defaults for every controller once. The idiomatic way is NestCrudModule.forRoot in your module:

ts
import { NestCrudModule } from '@ackplus/nest-crud';

@Module({
  imports: [
    NestCrudModule.forRoot({
      maxPerPage: 1000,      // or the legacy `maxPageSize` alias
      // messages: { ... },  // default response messages for all controllers
      // routes: { ... },    // override default route config globally
    }),
  ],
})
export class AppModule {}

Or call the underlying loader directly at bootstrap — equivalent:

ts
import { CrudConfigService } from '@ackplus/nest-crud';

CrudConfigService.load({ maxPerPage: 1000 });

Per-controller @Crud({ ... }) options always override these globals.

Call order

maxPerPage and messages are read per request, so they apply no matter when you load them. Global routes overrides are read when each @Crud() decorator runs (at import time), so load them before your CRUD controllers are imported — e.g. forRoot at the top of your root module's imports.

See also

  • Querying — every operator, relations, aggregates, having, hiding fields.
  • Packages & links — the npm and pub.dev client builders that produce these queries.