레이블이 REST인 게시물을 표시합니다. 모든 게시물 표시
레이블이 REST인 게시물을 표시합니다. 모든 게시물 표시

8/05/2022

Restful vs gRPC vs GraphQL

얼마전 프로젝트 진행 시, RESTful의 엔드포인트에 대해서 문제가 생겼었다. 구현상에 문제는 없지만 Addressability를 보장해야 하는 DX관점에서의 문제였다.

지금이야 REST로 API를 만들어서 제공하지만, 상황에 따라 gRPC 혹은 GraphQL을 사용해야 할 경우도 생기기에 각 표준에 대해서 정리하고자 한다.

통신 방식의 비교


이미지 출처: https://www.sensedia.com/post/apis-rest-graphql-or-grpc-who-wins-this-game


기술별 특성 비교


이미지 출처: https://www.sensedia.com/post/apis-rest-graphql-or-grpc-who-wins-this-game

REST

REST는 현재 가장 많이 사용되는 API 아키텍처이다. HTTP Method를 사용하여 리소스를 제공한다.

REST에서 사용되는 HTTP Method

  • POST: 새 리소스를 생성한다.
  • PUT: 리소스가 존재하는 경우 업데이트하거나 리소스가 없으면 생성한다.
  • DELETE: 리소스를 삭제한다.
  • PATCH: 기존 리소스를 부분적으로 업데이트 한다.
  • GET: 리소스를 쿼리한다.

REST의 장점은 아래와 같다.

  • 성능 - 빠른 반복 및 HTTP 표준 표현이 필요한 시스템에 가장 적합하다.
  • 확장성 - 많은 수의 구성 요소와 구성 요소 간의 상호 작용을 지원한다.
  • 단순성 - REST에는 아키텍처를 단순화하고 분리하는 균일한 인터페이스가 존재한다.

이미 오래전부터 사용되었기에 대부분의 개발자가 익숙하다는 장점이 있다. REST는 HTTP 프로토콜 디자인과 매우 밀접하게 브라우저 및 기타 HTTP 클라이언트는 기본적으로 REST API를 이해하고 있다.

하지만, REST는 만병 통치약이 아니고 유일한 API 아키텍처가 아니다. REST의 경우 리소스가 복잡할 수록 여러 API를 사용하거나 응답이 무거울 수 있다. 따라서 GraphQL로 대체되거나 gRPC를 사용하는 경우가 생기기도 한다. 그리고 REST에 대한 표준을 만들어야 한다. API를 만들때에 가장 중요한 것은 API를 사용하는 청중의 입장에서 설계하고 제공해야 한다. API 엔드포인트로 리소스를 제공하기에 하나의 API만 보면 안되고, 전체의 API의 엔드포인트를 보면서 문맥 및 의미하는 바가 잘 표현되었는지 확인해야 한다. 이 작업은 매우 어려운 작업이기에 매끄럽게 만들기가 어렵다. 이번에 발생한 것도 이 부분에서 문제가 발생한 것이다.

다른 API를 아키텍처를 사용할 이유가 없다면 REST가 가장 적합한 옵션이다. GraphQL, gRPC는 고유한 요구 사항이 있는 상황에 적합할 수 있다. 그리고 REST에 비해 학습 곡선이 가파르다.

범용적인 API가 필요할 경우 REST를 사용하면 좋다.

gRPC

gRPC는 Google에서 설계, 개발한 Google Remote Procedure Call이다. 데이터를 가볍고 빠르게 요청하기 위해 고려되었다. gPRC는 일반적인 원격 프로시저 호출보다 진화된 형태이다. gRPC를 사용하면 클라이언트는 원격 시스템이 마치 로컬인 것처럼 직접 메소드를 호출할 수 있다. gRPC는 프로토콜 버퍼(Protobufs)를 사용하여 데이터 전송을 위해 텍스트 기반의 JSON, XML이 아닌 바이너리로 직렬화된 데이터로 인터페이스를 정의한다. 또한 HTTP/1보다 더 안정적이고 빠른 HTTP/2를 사용하게 된다.

REST는 표준화된 용어를 통해 상호 작용을 정리하고 GraphQL은 생성된 스키마에 대해 요청을 실행하며 필요한 것을 가져오게 된다.

gRPC는 서버와 클라이언트 간의 관계에 의해 동작이 정의된다. 대부분의 권한은 클라이언트측에 의존하는 반면 처리 및 계산은 리소스를 제공하는 원격 서버에서 진행된다. 이점은 아래와 같다.

  • 가벼우며 클라이언트측의 리소스가 거의 필요하지 않다. 따라서 전력이 매우 부족한 상황에서 편리하게 이용할 수 있다.
  • 효율적이다. gRPC는 통신을 직렬화하는데 중점을 둔 구조화된 데이터 직렬화 방법인 protobufs를 사용한다.
  • 오픈소스 이며 자유롭게 사용, 수정 또는 분기할 수 있다.

gRPC는 정해진 양의 데이터 또는 클라이언트가 저전력이거나 리소를 보존하려는 시스템에 적합하다. 가장 좋은 예는 음성 컨트롤러, 스마트 조명 스위치, 화재 경보기, 잠금 장치 및 카메라와 같이 널리 사용되는 IoT 장치에 적용하면 장점을 최대한 이용할 수 있다.

GraphQL

GraphQL은 정확한 요청에 초점을 맞추고 필요한 것을 정확히 전달하기 위한 방식이다. GraphQL을 다른 API와 차별화하는 것은 클라이언트 중심의 접근 방식이다. 주요 이점은 아래와 같다.

  • 적응성 - 클라이언트가 원하는 데이터, 원하는 방식 및 형식을 결정한다.
  • 효율성 - 과도하게 가져오지 않고 클라이언트가 요청한 것을 정확하게 전달한다.
  • 유연성 - GraphQL은 크로스 플랫폼이며 12개 이상의 언어(Java, Perl, Python.,)을 지원한다.

GraphQL 사용 사례중 가장 많이 알려진 것은 Github이다. 확장성과 유연성 두 가지 주요 이유로 2016년에 전환했다. REST는 원하는 데이터를 얻기 위해 여러 요청을 해야 하고 각 요청에서 데이터를 과도하게 가져와야 하는 경우가 많다. Github의 급속한 성장과 수천만 명의 사용자를 보면 이것이 얼마나 부담되는 일인지 알 수 있다. GraphQL은 클라이언트가 특정 용도를 위해 특정 형식의 데이터를 요청할 수 있다는 점에 초점을 뒀기 때문에 Github의 Needs를 정확히 제공했다.

끝으로

각각의 기술은 고유한 장점과 단점이 존재한다. 목표가 무엇인지에 따라 어떤 것을 선택할지 결정되게 된다. 각 기술을 이해하고 현재 프로젝트에 가장 적합한 것이 무엇인지 판단하고 선택했으면 좋겠다.

References

  • https://medium.com/devops-dudes/graphql-vs-rest-vs-grpc-411a0a60d18d
  • https://konghq.com/blog/rest-vs-grpc-vs-graphql
  • https://www.sensedia.com/post/apis-rest-graphql-or-grpc-who-wins-this-game


5/03/2018

다양한 장치를 지원하는 REST API에 대해 고찰

“REST API는 일반적인 요청을 처리하는데 뛰어나며, 다수의 개발자가 API를 쉽게 사용할 수 있도록 하는 일련의 규칙을 수립합니다.”

위 모델에서는 모든 사람들이 규칙을 알고 있으면 엄청나게 강력해집니다. API 공급자는 일련의 규칙을 설정하고 API 소비자는 원하는 것을 얻으려면 공급자가 설정한 규칙을 준수해야 합니다.

그러나 점점 규모가 커지고 사람들이 디지털 콘텐츠 및 서비스를 사용하는 방식이 늘어나고 있는 상황에서는 위 단일 모델 원칙이 부족할 수 있습니다.

Netflix의 예를 들어 볼까요?

Netflix는 현재 게임 콘솔, 모바일, TV, 블루레이 플레이어, Tablet, PC 및 비디오를 스트리밍 할 수 있는 거의 모든 디바이스(약 800개 이상)에서 사용할 수 있습니다.

디바이스의 폭이 넓어지기 때문에 전체의 기능 변화를 관리하기가 어려워지는 잠재적인 문제가 발생합니다.

예를 들어 Google의 REST API는 일반적인 방식으로 디바이스의 요청을 처리 할 수 있지만, 그 중 어느것도 디바이스에 맞춰서 최적화하지 않았습니다. REST API가 데이터를 세부적으로 표현하는 리소스에 초점을 맞추기 때문입니다.

각 디바이스간의 차이점은 여러가지 경우가 존재합니다. 다음은 1:1 맞춤형 모델의 경우 지원하기 어려운 다기종 디바이스 기기간의 차이입니다.

  • 서로 다른 디바이스는 서로 다른 메모리 용량을 가지고 있음
  • 일부 디바이스는 고유하거나 독점적인 형식 혹은 전달 방법이 필요할 수 있음
  • 일부 디바이스는 더 Depth가 깊은 형태의 계층적 문서 모델로 성능이 향상될 수 있음
  • 디바이스마다 다른 화면 크기를 지니고 있기에 어떤 데이터가 필요한지에 영향을 줄 수 있음
  • 서로 다른 디바이스는 서로 다른 사용자 상호 작용 모델을 허용하며 메타 데이터 필드, 전달 방법, 상호 작용 모델등에 영향을 줄 수 있음

iPhone과 TV의 차이점과 다른 사용자 경험을 제공하는 방법과 TV에 투영되는 XBox와 Wii는 하드웨어 제약 조건과 상호 작용하는 방식이 서로 다르고 제약 조건을 지원하기 위해 서로 다른 API가 필요할 수 있습니다. 800가지가 넘는 다양한 디바이스 유형을 고려할 경우 분산해서 제공하는 방안이 압도적입니다. 그리고 더 많은 제조사가 디바이스를 계속 혁신함에 따라 편차가 커질 여지가 존재합니다.

이러한 기기의 차이 때문에 Netflix UI팀은 각 기기별 사용자에게 더 나은 서비스를 제공하기 위해 REST API를 Redesign하기로 결정 합니다.

위에서 언급한 것처럼 기존의 OSFA(One-size-fits-all) REST API 접근 방식에 제한 사항이 존재합니다. Netflix의 스트리밍 서비스는 800개 이상의 서로 다른 기기에서 사용할 수 있으며, 거의 모든 기기가 비공개 API로 부터 콘텐츠를 수신합니다. Netflix의 경우 OSFA API를 사용하여 다양한 기기를 지원하는 것은 성공했지만 API팀, UI팀 또는 Netflix 스트리밍 고객에게 적합하지 않음을 깨달았습니다.

새롭게 디자인 된 API의 핵심은 800개 이상의 기기 유형에서 다양한 차이가 있다는 사실을 수용한 점입니다. Netflix가 2008년 부터 사용한 REST API를 포함한 대부분의 API는 일반적인 방식으로 기기의 요청을 처리하여 서버쪽 구현을 보다 효율적으로 만듭니다. 이 접근법에는 충분한 이유가 있는데, API 팀이 OSFA API를 제공하면 모든 사람이 따라야 하는 규칙을 설정하기 때문에 광범위한 API사용자와 확고한 관계를 유지할 수 있기 때문입니다.

이런 규칙은 효과적이긴 하지만 OSFA의 문제점은 API 소비자가 아닌 API 제공업체가 편리하게 사용할 수 있다는 점입니다. 따라서 OSFA는 이러한 기기의 차이점을 무시합니다.

Netflix의 새로운 모델은 OSFA 패러다임을 없애고, 각 기기의 차이점을 동등하게 지원하면서 포용하도록 설계되었습니다. 이를 위해서 API 개발 플랫폼을 통해 각 UI팀은 사용자 정의를 만들 수 있습니다. 이렇게 하므로써, Request/Response 모델은 각 팀의 UI에 맞게 최적화 될 수 있습니다.

많은 OSFA 구현에서 API는 아래의 형태로 제공됩니다.


위의 그림은 Netflix 환경을 시작하기 위해 PS3에 필요한 여러 요청을 대략적으로 보여줍니다. 다른 UI는 OSFA REST API에 대해 유사한 상호 작용 세트를 갖게 됩니다. 이는 API에서 모두 동일한 규칙을 준수해야 한다는 것을 의미합니다. REST API내부에는 콘텐츠 수집, 준비 및 전달을 수행하는 엔진이 존재합니다.

Google의 새 API는 OSFA API 모델에서 전체 API의 관리 기능을 손상시키지 않으면서 세분화 맞춤 설정이 가능하게 하는 모델로 이전 되었습니다. 다음 그림은 수정된 아키텍처를 보여줍니다.


이 새로운 모델에서 UI는 사용자 요청에 대해 단일 지점을 만듭니다. 그 이후 사용자 요청에 대해 구문을 분석하고 Java API를 호출하는 처리기로 하부 API 제공 서비스를 호출합니다.

“클라이언트 코드”는 디바이스내에 있는 모든 코드를 의미합니다.

“서버 코드”는 서버에 존재하는 코드로 정의됩니다.

이 의미는 REST API의 경우에 경계를 나누는 기준이며, API 소비자와 API 제공자를 의미합니다.


Netflix의 경우 서버 코드에 많은 부분을 밀어 넣고 있습니다. 디바이스의 모든 코드는 클라이언트 코드로 간주되지만, 일부 클라이언트 코드는 서버에 위치합니다.

클라이언트 코드는 서버에 있는 전용 클라이언트 어댑터에 요청을 하게 됩니다.어댑터는 필요없는 필드 제거, 오류 처리 및 재시도, 응답 형식, 헤더 필드등의 정보를 처리합니다. 이 모든 처리는 특정 UI에 대한 사용자 정의입니다. 아래의 그림을 확인하세요.


위의 변화는 두 가지 측면이 있습니다.

첫째, 네트워크를 통해 진행되는 Request를 서버에서 처리하기 때문에 디바이스와 서버간의 효율적인 상호 작용이 가능합니다. 네트워크 비용은 트랜잭션 중 가장 비싸기 때문에 네트워크 요청 수를 줄이면 성능이 향상됩니다.

둘째, 최적화 된 어댑터를 구축해서 클라이언트 요청을 최종적으로 처리합니다.

이 접근 방식의 단점은 A/B 테스트 및 Multiple 테스트를 위해 더 많은 기기를 추가하고

더 많은 UI를 추가 할 경우 모든 개별 프로파일을 지원하는데 필요한 무수한 어댑터가 존재한다는 점입니다.

위에서 언급한 것처럼 일부 클라이언트 코드를 서버로 보내고 API를 제공하면 UI팀이 (API팀의 개입없이) 자체 어댑터 코드를 만들고 수정할 수 있으므로 개발 과정에서 훨씬 더 민첩할 수 있습니다. 이 들은 더 이상 규칙을 지시하거나 개발을 위한 병목이 되는 서버팀에 구속되지 않습니다. API 혁신은 UI팀에게 달려있게 됩니다.

UI팀이 HTML5, CSS3, JavaScript등의 기술에 더욱 숙련되어 있다는 점이 단점이긴 합니다.

이제는 서버측 기술을 배워야 합니다. 또 다른 문제는 UI팀이 서버 측 어댑터를 구현하기 때문에 리소스 집약적인 무한 루프 또는 기타 프로세스를 통해 API 서버를 중단시킬 가능성이 존재한다는 점입니다. 이를 보완하기 위해서 Netflix의 경우 Scrubbing Engine을 개발 하고 있습니다.

즉, OSFA 세계에서 장치의 코드는 서버를 쉽게 DDOS할 수 있으며, 서버에서 실행되는 경우 잠재적으로 더 큰 문제를 유발할 수 있습니다.

  1. PS3와 같은 기기는 네트워크를 통해 홈화면을 Load하는 단일 요청을 합니다. (이 코드는 PS3 UI팀에서 작성하고 지원)
  2. Groovy Adapter가 PS3 요청을 받고 구문 분석을 합니다. (PS3 UI 팀)
  3. Adapater는 하나의 요청을 Java API로 매핑 (PS3 UI 팀)
  4. 각 Java API는 요청에 필요한 콘텐츠를 제공하기 위해 종속 서비스를 호출
  5. Java API에서 종속 서비스 사용이 불가능하거나 4xx, 5xx를 반환하면 Java API는 Adapter(API팀)에 폴백 및 오류 코드를 반환합니다.
  6. Java API 트랜잭션이 성공적으로 완료되면 (API팀) 콘텐츠를 Adapter로 반환 합니다.
  7. Adapter가 콘텐츠를 조작하고, 원하는 요소를 가져오거나 잘라내고 오류를 처리 (PS3 UI 팀)
  8. Adapter는 PS3 홈 화면에 필요한 모든것을 포함하여 응답 형식을 지정합니다. (PS3 UI 팀)
  9. 클라이언트에게 Payload를 전달합니다. (PS3 UI 팀)
  10. 클라이언트가 구문을 분석하고 UI를 표현합니다. (PS3 UI 팀)

이 새로운 모델은 아직 초기 단계에 있으며, REST API를 사용하는 기기와 새로운 모델을 사용하는 기기로 현재 혼재되어 있습니다.

Source: https://medium.com/netflix-techblog/embracing-the-differences-inside-the-netflix-api-redesign-15fd8b3dc49d