API 설계 원칙

모든 API 는 크게 두가지 종류로 구분할 수 있다. 하나는 “정보를 조회”하는 목적의 API 이고, 하나는 “정보를 변경(생성)”하는 API 이다. 전자는 Query  method라고 하고, 후자는 Command method라고 부른다.

API를 설계할 때 이 두 가지 기준에 따라 적용되어야 하는 원칙(principle)같은 것이 있다. 당연하겠지만 Query method는 조회 결과에 해당하는 리턴값이 존재하겠지만, Command  method는 리턴값이 없는 void 타입으로 정의하자는 것이다. (HTTP (Rest) API 호출에서 Http Status 값은 해당 API의 리턴값으로 취급하지 않는다.)

 

Command method의 리턴값이 void가 아니게 되면 당장에는 큰 문제가 없을지도 모르지만, 향후에 성능이슈로 인해 해당 API를 비동기로 전환하게 되면 API를 사용하는 측에서는 그 변경에 대한 영향이 만만치 않다. 특히 많은 서비스로 분리되어 있는  MSA환경에서는 비동기로 API를 전환하고 기존 API 를 deprecate시키지 못하고 계속 끌고 가야 하는 상황이 생기게 된다.

 

그렇다면 void 타입의 Command method API를 호출하고 그 결과가 필요할 때는 어떻게 해야 할까?

 

첫 번째로 생각할 수 있는 방법은 callback 방식이다.  Requestor가 요청하는 command  message에 처리 결과를 받을 callback address 를 포함해서 요청하고, replier가 해당 요청을 처리한 후 callback address 에 결과를 push 해 주는 방법이다.

 

두 번째 방법은, EIP에서 제시하는 Request & Reply Pattern을 사용하는 것이다. ( http://www.enterpriseintegrationpatterns.com/patterns/messaging/RequestReply.html ) 간단하게 말하면 요청과 응답을 모두 message event로 전달하는 방식이다. 이 방법을 조금 확장하면 requestor 와 replier가 모두 publisher, subscriber 가 되는 EDA기반의 CQS 패턴을 생각해 볼 수 있게 된다. Publisher 는 subscriber가 누구이건 관심없이 이벤트를 발행하고, 관심있는 subscriber가 이를 구독해 가되, 자신에게 필요한 이벤트를 필터링 할 수 있는 Pipe & Filter 패턴을 함께 사용하는 것이다.

 

자칫하면 오히려 시스템의 복잡성이 커질 것 같기는 하지만, 관심영역을 잘 분리해 낼 수 있다면 효과적으로 단순함을 유지시킬 수도 있을 것 같다.

 

지금 사내의 복잡한 monolithic legacy 시스템을 micro service 로 전환하는 작업을 하고 있는데 아키텍처 스타일로 여러가지를 고민하고 있다. 이벤트 기반의 비동기 방식을 큰 줄기로 가져가고 싶은데 구세력의 저항이 만만치 않다. ㅋㅋ

댓글 남기기