Skip to content

Controllers

Michael Yali edited this page Jun 11, 2019 · 17 revisions

Description

@nestjsx/crud - core package which provides @Crud() controller decorator for endpoints generation, global configuration, validation, helper decorators.

Table of Contents

Install

npm i @nestjsx/crud class-transformer class-validator

Getting started

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.

API Endpoints

Crud() decorator generates the following API endpoints:

Get many resources

GET /heroes
GET /heroes/:heroId/perks

Result: array of resources | pagination object with data
Status Codes: 200

Get one resource

GET /heroes/:id
GET /heroes/:heroId/perks:id

Request Params: :id - some resource field (slug)
Result: resource object | error object
Status Codes: 200 | 404

Create one resource

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

Create many resources

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

Update one resource

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 one resource

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

Options

Crud() decorator accepts the following options:

model 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 options

{
  validation?: ValidationPipeOptions | false;
}

Optional
Accepts ValidationPipe options or false if you want to use your own validation implementation.

params options

{
  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 options

{
  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

Clone this wiki locally