E-commerce Application(Nest js Microservice) - 10. order-service와 catalog-service 통신(3)
#1 에러 케이스
이번 포스트에서는 다음의 케이스들을 다뤄보도록 하겠습니다.
1) ERROR_ORDER인 경우 재주문 요청
1)의 경우 사용자의 UI화면이 존재한다면 주문이 ERROR가 됐으므로 사용자에게 이에 관한 메시지를 보낼 것입니다. 그러면 사용자는 주문 취소 혹은 수량 변경 후 재주문을 해야겠죠. 여기서 2가지 케이스가 생기게 되네요. 이 케이스들을 다음과 같이 나누도록 하겠습니다.
1-1) 주문 취소의 경우 /orders/:orderId/cancel로 요청하기
1-2) 재주문의 경우 /orders/:orderId/reorder로 요청하기, 이 경우에는 기존의 reOrder메서드를 수정하도록 하겠습니다.
#2 1) 케이스
1-1)의 경우 기존에 만들어 두었던 cancelOrder로 대체할 수 있고, 이번 포스트에서는 1-2)의 경우만 다루도록 하겠습니다.
1-2) 재주문의 경우 /orders/:orderId/reorder로 요청하기
- request.update.ts
import { IsNotEmpty, IsNumber, IsString } from "class-validator";
export class RequestUpdate {
@IsNumber()
@IsNotEmpty()
readonly qty: number;
}
재주문할 경우 수량 수정을 위한 변수만 갖게 하도록 하겠습니다.
- order.controller.ts
import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common';
import { EventPattern } from '@nestjs/microservices';
import { OrderDto } from 'src/dto/order.dto';
import { RequestCreate } from 'src/vo/request.create';
import { RequestUpdate } from 'src/vo/request.update';
import { ResponseOrder } from 'src/vo/response.order';
import { OrderService } from './order.service';
@Controller('orders')
export class OrderController {
constructor(private readonly orderService: OrderService,) {}
...
@Post(':orderId/reorder')
public async reOrder(
@Param('orderId') orderId: string,
@Body() requestUpdate: RequestUpdate
) {
const orderDto = new OrderDto();
orderDto.orderId = orderId;
orderDto.qty = requestUpdate.qty;
return await this.orderService.reOrder(orderDto);
}
...
컨트롤러의 reOrder메서드를 다음과 같이 orderDto에 요청받은 정보값들을 담아 서비스단으로 넘기도록 하겠습니다.
- order.service.ts
import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { InjectRepository } from '@nestjs/typeorm';
import { OrderDto } from 'src/dto/order.dto';
import { OrderEntity } from 'src/entity/order.entity';
import { ResponseOrder } from 'src/vo/response.order';
import { Repository } from 'typeorm';
import { v4 as uuid } from 'uuid';
@Injectable()
export class OrderService {
constructor(
@InjectRepository(OrderEntity) private orderRepository: Repository<OrderEntity>,
@Inject('order-service') private readonly client: ClientProxy
) {}
...
public async reOrder(orderDto: OrderDto): Promise<ResponseOrder> {
try {
const orderEntity = await this.orderRepository.findOne({ where: { orderId: orderDto.orderId }});
const responseOrder = new ResponseOrder();
orderEntity.qty = orderDto.qty;
orderEntity.totalPrice = (Number(orderEntity.qty) * Number(orderEntity.unitPrice));
orderEntity.status = 'RE_ORDER';
this.client.emit("RE_ORDER", orderEntity);
await this.orderRepository.save(orderEntity);
responseOrder.orderId = orderEntity.orderId;
responseOrder.status = orderEntity.status;
return responseOrder;
} catch(err) {
throw new HttpException(err, HttpStatus.BAD_REQUEST);
}
}
...
}
그러면 서비스에서 비즈니스 로직이 다음과 같이 바뀌게 됩니다. 수량에 대한 변화가 생겼으니 orderEntity.qty의 수량을 변화시켜야 하고, orderEntity.totalPrice 또한 변화가 생겨야겠죠. 이렇게 reOrder에 관한 코드를 변경시키도록 하겠습니다.
#3 auth-service(추후 업로드)
이제 유저 정보를 확인하면 order에 관한 정보를 불러 올 수 있게 코드를 작성해보도록 하겠습니다. user-service.vo 디렉토리에 ResponseOrder라는 파일을 만들도록 하겠습니다.
- response.order.ts
import { IsBoolean, IsNotEmpty, IsNumber, IsString } from "class-validator";
export class ResponseOrder {
@IsString()
orderId: string;
@IsString()
productId: string;
@IsString()
productName: string;
@IsNumber()
qty: number;
@IsNumber()
unitPrice: number;
@IsNumber()
totalPrice: number;
@IsString()
userId: string;
@IsBoolean()
status: string;
}
- user.dto.ts
import { IsNumber, IsString } from 'class-validator';
import { ResponseOrder } from 'src/vo/response.order';
export class UserDto {
...
orders: ResponseOrder[];
}
- response.user.ts
import { ResponseOrder } from "./response.order";
export class ResponseUser {
email: string;
nickname: string;
encryptedPwd: string;
userId: string;
orders: ResponseOrder[];
}
그리고 ResponseUser에 ResponseOrder Array를 추가하겠습니다. 이 vo들은 user정보를 반환할 때 필요한 vo클래스입니다.
npm install --save nest-feign nest-consul-loadbalance nest-consul consul
- nestcloud/feign 연동을 지속적으로 해봤는데 잘 되지 않아 문서를 좀 더 찾아본 후 업로드하도록 하겠습니다.
#4 test
모든 코드가 대략적으로 완성된 것 같습니다. 그러면 시나리오를 다음과 같이 몇 가지를 구성해보고 테스트를 진행하도록 하겠습니다.
1) 회원가입 후 product-001의 제품을 10개 주문하기
2) product-001의 제품을 취소하기
3) 취소한 product-001의 제품을 20개로 바꾸어 재주문
4) product-002의 제품을 300개 주문하기
5) ERROR_ORDER상태 값인 product-002의 주문을 10개로 재주문
본 시나리오를 바탕으로 테스트를 진행해보도록 하겠습니다.
1) 회원가입 후 product-001의 제품을 10개 주문하기
2) product-001의 제품을 취소하기
3) 취소한 product-001의 제품을 20개로 바꾸어 재주문
4) product-002의 제품을 300개 주문하기
5) ERROR_ORDER상태 값인 product-002의 주문을 10개로 재주문
모든 시나리오들이 정상적으로 작동할 수 있는 모습을 볼 수 있습니다. 이로써 실제 서비스들에 대한 모든 코드를 구현해 봤습니다.
다른 시리즈인 Spring Cloud기반의 Microservice는 API Gateway Service를 이용해 하나의 포트로 모든 요청을 받고 각 서비스로 요청을 전달하고, 혹은 Spring Security를 이용해 인터셉터도 구현할 수 있습니다.
아직까지 NestJS가 미숙해서 위의 기능들을 구현할 수 있지만 제가 미처 구현 못한 것일수도 있으므로 위의 기능들과 관련해서 조금 더 공부를 하고 난 뒤 추가적으로 포스트를 한번 작성해보도록 하겠습니다. 감사합니다.
Author And Source
이 문제에 관하여(E-commerce Application(Nest js Microservice) - 10. order-service와 catalog-service 통신(3)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@biuea/E-commerce-ApplicationNest-js-Microservice-10.-order-service와-catalog-service-통신3저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)