REST vs gPRC

2020년 06월 14일

payload 포맷의 차이

  • 반드시 그래야 하는 것은 아니지만 현실에서 REST API는 일반적으로 JSON을 주고 받는다.
  • 반면 gRPC는 Protobuf(Protocol buffers) 메세지를 주고 받는다.
  • JSON은 text 포맷으로 교환 가능하고 사람이 읽고 분석할 수 있는 간단한 형태이다.
  • 반면 프로토버프는 바이너리 포맷이기에 위와 같은 장점이 없지만 JSON보다 사이즈가 작고 성능 면에서 일반적으로 더 뛰어나다. 그리고 JSON은 형태가 자유롭지만 프로토버프는 정해진 룰대로 스키마를 정의해야 하기 때문에 일관성 있는 포맷으로 앱 간에 데이터를 주고 받을 수 있다.

전송 프로토콜의 차이 (HTTP/1.1 vs HTTP/2)

  • REST 일반적으로 HTTP/1.1에 깊이 의존한다. HTTP/1.1은 플레인 텍스트를 주고 받는 request - response 모델을 사용한다.
  • 반면 gPRCHTTP/2 프로토콜을 사용한다. HTTP/2HTTP/1.1과 동일한 시멘틱을 공유하지만 (e.g. GET, POST 와 같은 메서드 / 헤더와 바디로 구성된 메세지 포맷 등) 메세지를 바이너리로 인코딩해서 주고 받는다는 커다란 차이가 있다.
  • HTTP/1.0의 경우 매번 새로운 리퀘스트에 대해서 TCP 커넥션을 새로 만들어야 했으므로 시간과 리소스를 더 소비했다. 이에 비해 HTTP/1.1은 지속적인 연결(persistant connection)을 가능하게 해서 하나의 TCP 커넥션이 유지된 채로, 응답을 기다릴 필요 없이 여러 개의 리퀘스트를 보낼 수 있다.

    • HTTP/1.1은 1.0에 비해 성능을 향상시켰지만 여전히 latency 이슈가 있다. 하나의 커넥션에 여러 개의 요청을 보낼 때, 이 요청들을 queue에 관리하므로 queue의 헤드 요청이 오래 걸리는 경우 뒤에 있는 요청들은 블로킹되는 병목현상이 나타난다. 이를 head-of-line(HOL) blocking 이라고 부른다.
    • 병렬적으로 여러 개의 TCP 커넥션을 만들면 이 문제를 완화할 수는 있지만, 클라이언트와 서버 사이에 동시에 유지할 수 있는 TCP 커넥션의 수가 제한되어 있을 뿐더러 TCP 커넥션을 새로 만들 때마다 추가적으로 리소스가 든다. (e.g. TCP handshake)
  • 반면 HTTP/2 는 하나의 TCP 연결이 여러 개의 양방향 스트림(bidirectional streams)을 지원한다. 하나의 커넥션은 여러 개의 스트림으로 구성되고, 각 스트림들은 여러 개의 메세지들(req-res 관계에서 주고 받는 포맷)로 구성되며 각 메세지들은 또 여러 개의 프레임으로 구성된다. 프레임들은 바이너리로 인코딩돼 있는 작은 단위이며, 특정 스트림에 속해 있다는 태그를 달고 있다. 이 식별 태그들은 커넥션이 인터리빙할 수 있게 해주고 결과적으로 블로킹 없이 여러 개의 요청-응답을 가능하게 한다. 즉 새로운 연결을 만들지 않고도 여러 개의 메세지가 병렬적으로 동시에 보낼 수 있는데 이를 Multiplexing 이라고 한다.

Ref

https://code.tutsplus.com/tutorials/rest-vs-grpc-battle-of-the-apis—cms-30711 - REST와 gRPC의 차이에 대해 개략적으로 쉽게 소개

https://developers.google.com/web/fundamentals/performance/http2 - http 2.0피처에 대해 자세한 소개

https://www.digitalocean.com/community/tutorials/http-1-1-vs-http-2-what-s-the-difference - http/1.1과 http/2.0 비교