NestJS에서 놀랍도록 빠르고 적은 코드 CRUD 작업 + OpenAPI 작성

소개



안녕하세요 여러분, 오늘은 CRUD 작업을 가장 빠르게 작성하는 방법을 알려드리겠습니다.

이 자습서에서는 CRUD 작업을 사용하여 간단한 ToDo 목록 백엔드를 만들고 mysql을 데이터베이스로 사용하고 ORM용 typeorm을 사용합니다. 쉬운 crud 작업을 위해 nestjsx/crud 패키지를 사용할 것입니다.

시작하기 전에 다음을 설치하고 구성했는지 확인하십시오.
  • MySQL
  • NestJS

  • 시작하자



    먼저 nest-cli를 사용하여 새 프로젝트를 생성해 보겠습니다.

    nest new crud-operation
    


    먼저 typeporm, mysql 라이브러리 및 dotenv를 설치합니다.

    npm install --save dotenv
    npm install --save @nestjs/typeorm typeorm mysql
    


    이제 .env 파일 및 데이터베이스 구성 서비스를 생성해 보겠습니다.

    touch .env
    mkdir src/shared && mkdir src/shared/services
    touch src/shared//services/database-connection.service.ts
    

    .env 파일을 열고 데이터베이스 자격 증명을 구성하고 자신의 데이터베이스 자격 증명을 입력했는지 확인하십시오.

    DATABASE_HOST = "localhost"
    DATABASE_PORT = 3306
    DATABASE_USER = "root"
    DATABASE_PASSWORD = "root"
    DATABASE_DB = "nestjs_crud"
    


    이제 database-connection.service.ts를 열고 다음 코드를 추가해 보겠습니다.

    import { Injectable } from '@nestjs/common'
    import { TypeOrmOptionsFactory, TypeOrmModuleOptions } from '@nestjs/typeorm'
    import 'dotenv/config'
    
    @Injectable()
    export class DatabaseConnectionService implements TypeOrmOptionsFactory {
    
      createTypeOrmOptions(): TypeOrmModuleOptions {
        return {
          name: 'default',
          type: 'mysql',
          host: process.env.DATABASE_HOST,
          port: Number(process.env.DATABASE_PORT),
          username: process.env.DATABASE_USER,
          password: process.env.DATABASE_PASSWORD,
          database: process.env.DATABASE_DB,
          synchronize: true,
          dropSchema: false,
          logging: true,
          entities: ['dist/**/*.entity.js'],
        }
      }
    }
    


    데이터베이스 연결 서비스를 생성한 후 TypeOrmModule을 구성하고 데이터베이스 연결 서비스를 사용하여 TypeOrmModule 가져오기를 엽니다app.module.ts.

    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { TypeOrmModule } from '@nestjs/typeorm';
    import { DatabaseConnectionService } from './shared/services/database-connection.service';
    
    @Module({
      imports: [
        TypeOrmModule.forRootAsync({
          useClass: DatabaseConnectionService
        })
      ],
      controllers: [AppController],
      providers: [AppService],
    })
    export class AppModule {}
    


    이제 데이터베이스 연결을 구성했으므로 다음 명령을 사용하여 응용 프로그램을 실행할 수 있습니다.

    npm run start:dev
    


    이제 컴파일 및 빌드를 기다리면 다음이 표시됩니다.


    이제 todo 모듈, 서비스 및 컨트롤러를 만들어 보겠습니다.

    nest g module todo
    nest g service todo
    nest g controller todo
    


    todo 모듈을 만든 후 서비스 및 컨트롤러에서 nestjsx/crud를 설치할 수 있습니다.

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


    이제 todo 엔터티(데이터베이스 엔터티)를 생성해 보겠습니다.

    touch src/todo/todo.entity.ts
    

    todo.entity.ts를 열고 todo 엔터티를 생성해 보겠습니다.

    import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from "typeorm";
    
    @Entity('todos')
    export class TodoEntity {
    
      @PrimaryGeneratedColumn() 
      id: number;
    
      @Column() 
      title: string;
    
      @Column()
      description: string
    
      @Column({
        type: 'boolean',
        default: false
      })
      is_done: boolean
    
      @CreateDateColumn()
      create_at: Date
    
      @UpdateDateColumn()
      updated_at: Date
    }
    


    데이터베이스에 todos 테이블을 성공적으로 생성했습니다.

    이제 CRUD 작업을 시작하고 todo.service.ts를 열고 다음 코드를 작성해 보겠습니다.

    import { Injectable } from '@nestjs/common';
    import { TypeOrmCrudService } from "@nestjsx/crud-typeorm";
    import { TodoEntity } from './todo.entity';
    import { InjectRepository } from '@nestjs/typeorm';
    
    @Injectable()
    export class TodoService extends TypeOrmCrudService<TodoEntity>{
      constructor(@InjectRepository(TodoEntity) repo) {
        super(repo)
      }
    }
    


    이제 todo.controller.ts를 열고 다음을 작성해 보겠습니다.

    import { Controller } from '@nestjs/common';
    import { Crud, CrudController } from '@nestjsx/crud';
    import { TodoEntity } from './todo.entity';
    import { TodoService } from './todo.service';
    
    @Crud({
      model: {
        type: TodoEntity
      }
    })
    
    @Controller('todo')
    export class TodoController implements CrudController<TodoEntity> {
      constructor(public service: TodoService) {}
    }
    


    이 시점에서 우리는 서비스와 컨트롤러 및 물론 CRUD 작업을 거의 완료했습니다. TypeOrmModule을 가져오고 todo.module.ts에서 TodoEntity를 사용하기만 하면 todo.module.ts를 열 수 있습니다.

    import { Module } from '@nestjs/common';
    import { TodoService } from './todo.service';
    import { TodoController } from './todo.controller';
    import { TypeOrmModule } from '@nestjs/typeorm';
    import { TodoEntity } from './todo.entity';
    
    @Module({
      imports: [
        TypeOrmModule.forFeature([TodoEntity])
      ],
      providers: [TodoService],
      controllers: [TodoController]
    })
    export class TodoModule {}
    


    이 시점에서 CRUD 작업이 완료되었습니다. 이제 WTF가 어디에 있는지 궁금할 것입니다.
    , @Get, @Put, @Patch, @Delete 메소드?? Nestjs/Crud 패키지는 이를 자동으로 처리하지만 자체 사용자 지정 논리를 원하는 경우 다른 방법을 재정의할 수 있습니다. 위키로 이동하여 자세한 정보를 확인하세요. 이제 OpenAPI를 설정하겠습니다. 이를 위해 nestjs swagger를 사용할 것입니다.

    npm install --save @nestjs/swagger swagger-ui-express
    


    swagger를 설치한 후 main.ts를 열 수 있습니다.

    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
    
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
    
      const options = new DocumentBuilder()
        .setTitle('Todo Crud')
        .setDescription('The todo API description')
        .setVersion('1.0')
        .addTag('todo')
        .build();
      const document = SwaggerModule.createDocument(app, options);
      SwaggerModule.setup('api/docs', app, document);
    
      await app.listen(3000);
    }
    bootstrap();
    


    이제 openAPI가 구성되어 액세스할 수 있습니다http://localhost:3000/api/docs.


    이제 우리는 우리의 다른 todo 끝점을 볼 수 있습니다. 그러나 우리의 openAPI는 현재 제대로 문서화되어 있지 않습니다. 예를 들어 이 스크린샷과 같이 할 일을 생성하는 데 필요한 필드가 무엇인지 보여주기 위해 api 태그를 추가해야 합니다.


    비어 있지 않습니까?, 게시물 요청의 필드가 무엇인지 모릅니다.

    이 문제를 해결하려면 엔티티 파일의 열에 @ApiProperty()를 추가해야 합니다. todo.entity.ts를 열고 데코레이터를 추가해 보겠습니다.

    import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from "typeorm";
    import { ApiProperty } from "@nestjs/swagger";
    
    @Entity('todos')
    export class TodoEntity {
    
      @PrimaryGeneratedColumn() 
      id: number;
    
      @ApiProperty()
      @Column() 
      title: string;
    
      @ApiProperty()
      @Column()
      description: string
    
      @ApiProperty()
      @Column({
        type: 'boolean',
        default: false
      })
      is_done: boolean
    
      @CreateDateColumn()
      create_at: Date
    
      @UpdateDateColumn()
      updated_at: Date
    }
    


    페이지를 새로 고치면 이제 필드를 볼 수 있습니다.



    이제 crud 작업을 테스트할 수 있습니다.


    그 외에도 nestjs/crud는 페이지 매김, 필터 등과 같은 다양한 옵션을 제공합니다.


    페이지 매김, 자신의 필터 작성 등에 대해 걱정할 필요가 없습니다. 빠르고 정확하고 코드가 적습니다.

    더 많은 것을 탐색하고 더 깊이 들어가고 싶다면 nestjsx/crud wiki 및 repo를 확인할 수 있습니다.
  • 위키: https://github.com/nestjsx/crud/wiki
  • 레포: https://github.com/nestjsx/crud
  • 좋은 웹페이지 즐겨찾기