CRUD

CRUD

This chapter applies only to TypeScript

CRUD 패키지 (@nestjsx/crud)를 사용하면 CRUD 컨트롤러 및 서비스를 쉽게 만들 수 있으며 RESTful API를 위한 다양한 기능을 즉시 사용할 수 있습니다.

  • 데이터베이스에 관계없이 확장 가능한 CRUD 컨트롤러

  • 필터링, 페이지 매김, 정렬, 관계, 중첩 관계, 캐시 등을 사용하여 쿼리 문자열 구문 분석

  • 프론트 엔드 사용을 위한 쿼리 빌더가 있는 프레임 워크에 구애받지 않는 패키지

  • 쿼리, 경로 매개 변수 및 DTO 유효성 검사

  • 컨트롤러 메소드를 쉽게 재정의

  • 작지만 강력한 구성 (글로벌 구성 포함)

  • 추가 헬퍼 데코레이터

  • Swagger 다큐먼트

warning 알림 지금까지@nestjsx/crudTypeORM 만 지원하지만 SequelizeMongoose와 같은 다른 ORM도 가까운 시일 내에 포함될 예정입니다. 따라서 이 기사에서는 TypeORM을 사용하여 CRUD 컨트롤러 및 서비스를 작성하는 방법에 대해 설명합니다. @nestjs/typeorm 패키지를 이미 성공적으로 설치하고 설정했다고 가정합니다. 자세한 내용은 여기를 참조하십시오.

Getting started

CRUD 기능 생성을 시작하려면 필요한 모든 종속성을 설치해야 합니다.

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

프로젝트에 이미 일부 엔터티가 있다고 가정합니다.

@@filename(hero.entity)
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

@Entity()
export class Hero {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column({ type: 'number' })
  power: number;
}

우리가 해야 할 첫번째 단계는 service를 만드는 것입니다.

@@filename(heroes.service)
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { TypeOrmCrudService } from '@nestjsx/crud-typeorm';
import { Hero } from './hero.entity';

@Injectable()
export class HeroesService extends TypeOrmCrudService<Hero> {
  constructor(@InjectRepository(Hero) repo) {
    super(repo);
  }
}

서비스가 완료되었으므로 컨트롤러를 만들어 봅시다 :

@@filename(heroes.controller)
import { Controller } from '@nestjs/common';
import { Crud } from '@nestjsx/crud';
import { Hero } from './hero.entity';
import { HeroesService } from './heroes.service';

@Crud({
  model: {
    type: Hero,
  },
})
@Controller('heroes')
export class HeroesController {
  constructor(public service: HeroesService) {}
}

마지막으로 모듈에 모든 것을 연결해야합니다.

@@filename(heroes.module)
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

import { Hero } from './hero.entity';
import { HeroesService } from './heroes.service';
import { HeroesController } from './heroes.controller';

@Module({
  imports: [TypeOrmModule.forFeature([Hero])],
  providers: [HeroesService],
  controllers: [HeroesController],
})
export class HeroesModule {}

warning 알림 HeroesModule을 루트 ApplicationModule로 가져 오는 것을 잊지 마십시오.

이후에 Nest 애플리케이션에는 다음과 같이 새로 작성된 엔드 포인트가 있습니다.

  • GET /heroes - get many heroes.

  • GET /heroes/:id - get one hero.

  • POST /heroes/bulk - create many heroes.

  • POST /heroes - create one hero.

  • PATCH /heroes/:id - update one hero.

  • PUT /heroes/:id - replace one hero.

  • DELETE /heroes/:id - delete one hero.

Filtering and pagination

CRUD provides rich tools for filtering and pagination. Example request:

info Request GET /heroes?select=name&filter=power||gt||90&sort=name,ASC&page=1&limit=3

이 예에서는 히어로 목록을 요청하고 히어로의 파워가 90보다 큰 name속성만 선택하고 1 페이지 내에서 결과 제한을 3으로 설정했습니다. ASC 순서로 name으로 정렬됩니다.

응답 객체는 다음과 비슷합니다.

{
  "data": [
    {
      "id": 2,
      "name": "Batman"
    },
    {
      "id": 4,
      "name": "Flash"
    },
    {
      "id": 3,
      "name": "Superman"
    }
  ],
  "count": 3,
  "total": 14,
  "page": 1,
  "pageCount": 5
}

warning 알림 기본 열은 요청 여부에 관계없이 리소스 응답 개체에 유지됩니다. 우리의 경우에는 id 열입니다.

쿼리 매개 변수 및 필터 연산자의 전체 목록은 프로젝트의 Wiki에서 찾을 수 있습니다.

Relations

언급할 가치가 있는 또 다른 기능은 "관계"입니다. CRUD 제어기에서 API 호출 내에서 페치할 수 있는 엔티티 관계 목록을 지정할 수 있습니다.

@Crud({
  model: {
    type: Hero,
  },
  join: {
    profile: {
      exclude: ['secret'],
    },
    faction: {
      eager: true,
      only: ['name'],
    },
  },
})
@Controller('heroes')
export class HeroesController {
  constructor(public service: HeroesService) {}
}

@Crud()데코레이터 옵션에서 허용된 관계를 지정한 후 다음과 같은 요청을 할 수 있습니다.

info Request GET /heroes/25?join=profile||address,bio

응답에는 addressbio 열이 선택되고 결합된 프로파일을 가진 hero 객체가 포함됩니다.

또한 응답에는 eager: true로 설정되어 있으므로 모든 응답에서 지속되므로 name 열이 선택된 faction 오브젝트가 포함됩니다.

프로젝트의 WiKi에서 관계에 대한 자세한 정보를 찾을 수 있습니다.

Path params validation

기본적으로 CRUD는 이름이 id인 슬러그를 생성하고 number로 유효성을 검사합니다.

그러나 이 동작을 변경할 가능성이 있습니다. 엔티티에 기본 열 _id (UUID 문자열)가 있고 이를 엔드 포인트의 슬러그로 사용해야 한다고 가정하십시오. 이 옵션을 사용하면 다음과 같은 작업을 쉽게 수행할 수 있습니다.

@Crud({
  model: {
    type: Hero,
  },
  params: {
    _id: {
      field: '_id',
      type: 'uuid',
      primary: true,
    },
  },
})
@Controller('heroes')
export class HeroesController {
  constructor(public service: HeroesService) {}
}

더 많은 params 옵션은 프로젝트의 Wiki를 참조하십시오.

Request body validation

요청 본문 유효성 검사는 각 POST, PUT, PATCH 요청에 Nest ValidationPipe를 적용하여 기본적으로 수행됩니다. 우리는 @Crud()데코레이터 옵션의 model.type을 유효성 검사 규칙을 설명하는 DTO로 사용합니다.

이를 제대로 수행하기 위해 validation groups를 사용합니다.

@@filename(hero.entity)
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
import { IsOptional, IsDefined, IsString, IsNumber } from 'class-validator';
import { CrudValidationGroups } from '@nestjsx/crud';

const { CREATE, UPDATE } = CrudValidationGroups;

@Entity()
export class Hero {
  @IsOptional({ always: true })
  @PrimaryGeneratedColumn()
  id: number;

  @IsOptional({ groups: [UPDATE] })
  @IsDefined({ groups: [CREATE] })
  @IsString({ always: true })
  @Column()
  name: string;

  @IsOptional({ groups: [UPDATE] })
  @IsDefined({ groups: [CREATE] })
  @IsNumber({}, { always: true })
  @Column({ type: 'number' })
  power: number;
}

warning 알림 createupdate 조치에 대해 별도의 DTO 클래스를 완전히 지원하는 것은 다음 CRUD 릴리스의 주요 우선 순위 중 하나입니다.

Routes options

@Crud()데코레이터를 적용하여 생성되는 특정 경로만 비활성화하거나 활성화 할 수 있습니다.

@Crud({
  model: {
    type: Hero,
  },
  routes: {
    only: ['getManyBase'],
    getManyBase: {
      decorators: [
        UseGuards(HeroAuthGuard)
      ]
    }
  }
})
@Controller('heroes')
export class HeroesController {
  constructor(public service: HeroesService) {}
}

또한 메소드 데코레이터를 특정 경로 decorators 배열에 전달하여 모든 메소드 데코레이터를 적용할 수 있습니다. 기본 메소드를 재 정의하지 않고 일부 데코레이터를 추가할 때 편리합니다.

Documentation

이 챕터의 예는 CRUD 기능 중 일부만 다룹니다. 프로젝트의 Wiki 페이지에서 더 많은 사용 질문에 대한 답변을 찾을 수 있습니다.

Last updated