basic
nest g resource
를 이용하면 CRUD entry points 를 포함한 대부분의 기본적인 보일러 플레이트들을 자동으로 생성해준다. 해당 resource 의 이름을 TestUser
라고 가정하자.
# 예시
:~/environment $ nest g resource
? What name would you like to use for this resource (plural, e.g., "
users")? test-user
? What transport layer do you use? REST API
? Would you like to generate CRUD entry points? Yes
CREATE test-user/test-user.controller.spec.ts (598 bytes)
CREATE test-user/test-user.controller.ts (971 bytes)
CREATE test-user/test-user.module.ts (270 bytes)
CREATE test-user/test-user.service.spec.ts (475 bytes)
CREATE test-user/test-user.service.ts (665 bytes)
CREATE test-user/dto/create-test-user.dto.ts (34 bytes)
CREATE test-user/dto/update-test-user.dto.ts (186 bytes)
CREATE test-user/entities/test-user.entity.ts (25 bytes)
# tree
test-user
├── dto
│ ├── create-test-user.dto.ts
│ └── update-test-user.dto.ts
├── entities
│ └── test-user.entity.ts
├── test-user.controller.spec.ts
├── test-user.controller.ts
├── test-user.module.ts
├── test-user.service.spec.ts
└── test-user.service.ts
생성된 resource 를 통해 간단한 CRUD 를 구현해보자.
test-user.entity.ts
에 db 와 연결되는 model 을 작성한다. 사용된 ORM 은 sequelize 이다.
// test-user/entities/test-user.entity.ts
...
@Table({
tableName: "tb_test_user",
paranoid: true, // deletedAt column 을 생성하여 실제로 삭제되지 않았으나 삭제된 것처럼 구현할 수 있게 해준다
freezeTableName: true, // TableName을 Model을 설정할 때의 이름 그대로 사용하게 해준다 ... false 일 경우 복수형으로 변경된다
timestamps: true, // 테이블을 생성한 후 자동적으로 createdAt, updatedAt column 을 생성한다
})
export class TestUser extends Model {
@Column({
primaryKey: true,
type: DataType.STRING(14),
})
user_no!: string;
@Column({
type: DataType.STRING(50),
allowNull: false,
})
user_id!: string;
...
엔터티에서 export 시킨 TestUser
클래스를 SequelizeModule.forFeature()
method 를 사용하여 모듈에 imports 시켜주어야 한다. #이유
imports 시켜주지 않을 경우, ERROR [ExceptionHandler] Nest can't resolve dependencies of the TestUserService...
라는 dependency 에러를 만날 수 있다.
// test-user/test-user.module.ts
import { Module } from "@nestjs/common";
import { TestUserService } from "./test-user.service";
import { TestUserController } from "./test-user.controller";
import { TestUser } from "./test-user.entity";
import { SequelizeModule } from "@nestjs/sequelize";
@Module({
imports: [SequelizeModule.forFeature([TestUser])],
controllers: [TestUserController],
providers: [TestUserService],
})
export class TestUsersModule {}
SequelizeModule.forFeature()
method 를 통해 정의한 모델은 service 레이어에서 InjectModel()
데코레이터를 통하여 inject 해줄 수 있다.
아래의 모습과 같다.
// test-user/test-user.service.ts
import { Injectable } from "@nestjs/common";
import { InjectModel } from "@nestjs/sequelize";
import { Sequelize } from "sequelize-typescript";
import { CreateTestUserDto } from "./dto/create-test-user.dto";
import { UpdateTestUserDto } from "./dto/update-test-user.dto";
import { TestUser } from "./test-user.entity";
@Injectable()
export class TestUserService {
constructor(
@InjectModel(TestUser)
private readonly testuserModel: typeof TestUser,
private readonly sequelize: Sequelize
) {}
...
위에서 정의해 둔 모델을 통해 유저 정보를 가져오는 logic 을 생성해보자.
먼저 service layer 에서 sequelize where 절을 이용하여 user_no 가 같은 것을 가져오는 findOne
함수를 생성한다. controller 에서 들어온 요청을 service layer 의 findOne
함수로 리턴해주면 함수 내부에 정의된 logic 을 수행한다.
// test-user/test-user.service.ts
...
findOne(user_no: string) {
const user = this.testuserModel.findOne({
where: {
user_no: user_no,
},
});
return user;
}
...
// test-user/test-user.controller.ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
UseGuards,
} from "@nestjs/common";
import { TestUserService } from './test-user.service';
import { CreateTestUserDto } from './dto/create-test-user.dto';
import { UpdateTestUserDto } from './dto/update-test-user.dto';
@Controller('test-user')
export class TestUserController {
constructor(private readonly testUserService: TestUserService) {}
@Get('/:user_no')
findOne(@Param("user_no") user_no: string) {
return this.testUserService.findOne(user_no);
}
}
controller 는 엔드포인트로, 들어오는 parameter 와 그 타입을 설정할 수 있다. resource 를 생성하고 난 직후의 controller 는 아래의 형태로 생겼다. HTTP request method 를 설정하기 위해서 @Get
과 같은 형태의 HTTP request method decorator 를 사용한다.
@Param
decorator 를 사용하여 parameter 값을 설정한다. query parameter 를 설정할 때에는 @Query
decorator 를 사용한다.
이번에는 유저를 생성하는 logic 을 생성해보자. dto 단에 유저 생성을 위한 parameter 값들을 따로 정의한 CreateTestUserDto
클래스를 생성한다.
// test-user/dto/create-test-user.dto.ts
import { IsString } from "class-validator";
export class CreateTestUserDto {
@IsString()
readonly user_id!: string;
@IsString()
readonly password!: string;
}
export 시킨 CreateTestUserDto
클래스를 이용하여 request 의 @Body
를 통해 들어오는 값들을 정의해 둔 createTestUserDto
에 담아 service layer 에 위치한 create
함수로 보내면, 함수 내부에 정의된 logic 을 수행하여 user 정보를 create 해준다.
// test-user/test-user.contoller.ts
...
@Post()
create(@Body() createTestUserDto: CreateTestUserDto) {
return this.testUserService.create(createTestUserDto);
}
// test-user/test-user.service.ts
...
create(createTestUserDto: CreateTestUserDto) {
const dto = {
...createTestUserDto,
};
return this.testuserModel.create(dto);
}
...
'nest.js' 카테고리의 다른 글
practice 2 (0) | 2021.09.27 |
---|---|
Nest.js (0) | 2021.07.22 |