개발/Node & Javascript
Nest.js 탐험기 5 - microservice (grpc) 를 사용해보자 - 통신방식 구현
말고기
2022. 1. 23. 19:38
728x90
반응형
개요
- GRPC의 통신방식은 크게 4가지 방식이 존재한다. (unary, server streaming, client streaming, bidirectional-streaming)
- 이를 nest.js에서 구현해보도록 하자.
- 기본적으로 GRPC에 관한 내용은 GRPC 정의 및 통신 방식, 기본 구현은 GRPC 기본 구현을 살펴보고 오면 좋다.
통신방식
1. unary
- 해당 부분은 GRPC 기본 구현에 구현이 되어 있으므로 해당 내용을 참조하도록 하자.
2. server streaming
- 해당 방식은 단일 client 요청에 여러 server response를 보낼 때 사용한다.
- 이전에 구현했던 hero.proto 파일에 추가해보자.
- cf) repeated는 단일 message안에서 여러개의 item을 보내지만 stream은 여러개의 message를 보내는 방식으로 차이가 있다는걸 꼭 기억해두자.
- hero.proto 수정
아래와 같이 rpc method를 추가해준다.
service HeroesService {
...
rpc Find(Void) returns (stream Hero) {}
}
message Void {}
- heroes.controller.ts 수정
@Controller()
export class HeroesController {
@GrpcMethod('HeroesService', 'Find')
find(data: Void, metadata?: Metadata, call?: ServerDuplexStream<any, any>): Observable<Hero> {
const items = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Doe' },
{ id: 3, name: 'malgogi' },
{ id: 4, name: 'malgogi2' },
{ id: 5, name: 'malgogi3' },
];
return from(items);
}
...
}
- hero.client.service.ts
- 사용하는 쪽에서는 아래와 같이 설정한다.
@Injectable()
export class HeroClientService implements OnModuleInit {
...
findMany(): Observable<Hero[]> {
return this.heroesController.find({})
.pipe(toArray());
}
}
3. client streaming
- 해당 방식은 client 가 여러 message 를 보내고 이를 단일 server message를 보내는 방식이다.
- hero.proto 수정
service HeroesService {
rpc FindsAny(stream HeroById) returns (Hero) {}
...
}
message HeroById {
int32 id = 1;
}
- hero.controller.ts 수정
@Controller()
export class HeroesController {
@GrpcStreamMethod('HeroesService', 'FindsAny')
findsAny(messages: Observable<HeroById>, metadata?: Metadata, call?: ServerReadableStream<any, any>): Observable<Hero> {
return messages
.pipe(last(), map(item => {
return {
id: item.id,
name: 'malgogi'
};
}));
}
...
}
- hero.client.service.ts 수정
@Injectable()
export class HeroClientService implements OnModuleInit {
...
findOneByAny(): Observable<Hero> {
const observable = from([{ id: 1 }, { id: 2 }, { id: 3 }]);
return this.heroesController.findsAny(observable);
}
}
4. bidirectional-streaming
- 해당 방식은 message를 서로 주고 받는 형태로 통신한다.
- 반드시 요청 message 한개가 응답 message 한 개일 필요는 없다.
- hero.proto 수정
service HeroesService {
rpc Commute(stream HeroById) returns (stream Hero) {}
}
- hero.controller.ts 수정
@Controller()
export class HeroesController {
@GrpcStreamMethod('HeroesService', 'Commute')
commute(messages: Observable<HeroById>, metadata: Metadata, call: ServerDuplexStream<any, any>): Observable<Hero> {
const subject = new Subject<Hero>();
const onNext = message => {
subject.next({
id: 1,
name: message.name,
});
};
const onComplete = () => subject.complete();
messages.subscribe({
next: onNext,
complete: onComplete,
});
return subject.asObservable();
}
}
- hero.client.service.ts 수정
@Injectable()
export class HeroClientService implements OnModuleInit {
...
commute(): Observable<Hero[]> {
return this.heroesController.commute(from([{ id: 1 }, { id: 2 }, { id: 3 }]))
.pipe(toArray());
}
}
결론
- 이번에는 grpc의 통신방식을 nest.js로 구현해보았다.
- 다음에는 grpc의 여러 부가 기능들을 하나씩 다뤄보려고 한다.
출처
728x90
반응형