-
-
Notifications
You must be signed in to change notification settings - Fork 572
Controllers
@nestjsx/crud - core package which provides @Crud()
controller decorator for endpoints generation, global configuration, validation, helper decorators.
npm i @nestjsx/crud class-transformer class-validator
Let's take a look at the example of using @nestjsx/crud
with TypeORM.
Assume we have some TypeORM enitity:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class Company {
@PrimaryGeneratedColumn() id: number;
@Column() name: string;
}
Then we need to create a service:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { TypeOrmCrudService } from '@nestjsx/crud-typeorm';
import { Company } from './company.entity';
@Injectable()
export class CompaniesService extends TypeOrmCrudService<Company> {
constructor(@InjectRepository(Company) repo) {
super(repo);
}
}
We've done with the service so let's create a controller:
import { Controller } from '@nestjs/common';
import { Crud } from '@nestjsx/crud';
import { Company } from './company.entity';
import { CompaniesService } from './companies.service';
@Crud({
model: {
type: Company,
},
})
@Controller('companies')
export class CompaniesController {
constructor(public service: CompaniesService) {}
}
All we have to do next is to connect our service and controller in the CompaniesModule
as we usually do:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Company } from './company.entity';
import { CompaniesService } from './companies.service';
import { CompaniesController } from './companies.controller';
@Module({
imports: [TypeOrmModule.forFeature([Company])],
providers: [CompaniesService],
exports: [CompaniesService],
controllers: [CompaniesController],
})
export class CompaniesModule {}
That's it.
Crud()
decorator generates the following API endpoints:
GET /heroes
GET /heroes/:heroId/perks
Result: array of resources | pagination object with data
Status Codes: 200
GET /heroes/:id
GET /heroes/:heroId/perks:id
Request Params: :id
- some resource field (slug)
Result: resource object | error object
Status Codes: 200 | 404
POST /heroes
POST /heroes/:heroId/perks
Request Body: resource object | resource object with nested (relational) resources
Result: created resource object | error object
Status Codes: 201 | 400
POST /heroes/bulk
POST /heroes/:heroId/perks/bulk
Request Body: array of resources objects | array of resources objects with nested (relational) resources
{
"bulk": [{ "name": "Batman" }, { "name": "Batgirl" }]
}
Result: array of created resources | error object
Status codes: 201 | 400
PATCH /heroes/:id
PATCH /heroes/:heroId/perks/:id
Request Params: :id
- some resource field (slug)
Request Body: resource object (or partial) | resource object with nested (relational) resources (or partial)
Result:: updated partial resource object | error object
Status codes: 200 | 400 | 404
DELETE /heroes/:id
DELETE /heroes/:heroId/perks/:id
Request Params: :id
- some resource field (slug)
Result:: empty | resource object | error object
Status codes: 200 | 404
Crud()
decorator accepts the following options:
{
model: {
type: Entity|Model|DTO
},
}
Required
Entity
, Model
or DTO
class must be provided here. Everything else described bellow is optional. It's needed for a built in validation based on NestJS ValidationPipe
.
{
validation?: ValidationPipeOptions | false;
}
Optional
Accepts ValidationPipe
options or false
if you want to use your own validation implementation.
{
params?: {
[key: string]: {
field: string;
type: 'number' | 'string' | 'uuid';
primary?: boolean;
},
},
}
Optional
By default @Crud()
decorator will use id
with the type number
as a primary slug param.
If you have, for instance, a resorce field called slug
or whatever, it's a UUID and you need it to be a primary slug by which your resource should be fetched, you can set up this params options:
{
params: {
slug: {
field: 'slug',
type: 'uuid',
primary: true,
},
},
}
If you have a controller path with that looks kinda similar to this /companies/:companyId/users
you need to add this param option:
{
params: {
...
companyId: {
field: 'companyId',
type: 'number'
},
},
}
{
routes?: {
getManyBase?: {
interceptors?: [],
decorators?: [],
},
getOneBase?: {
interceptors?: [],
decorators?: [],
},
createOneBase?: {
interceptors?: [],
decorators?: [],
},
createManyBase?: {
interceptors?: [],
decorators?: [],
},
updateOneBase: {
interceptors?: [],
decorators?: [],
allowParamsOverride?: boolean,
},
deleteOneBase?: {
interceptors?: [],
decorators?: [],
returnDeleted?: boolean,
},
}
}
Optional
It's a set of options for each of the generated routes.
interceptors
- an array of your custom interceptors
decorators
- an array of your custom decorators
allowParamsOverride
- whether or not to allow body data be overriten by the URL params on PATH request. Default: false
returnDeleted
- whether or not an entity object should be returned in the response body on DELETE request. Default: false