블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

API 게이트 웨이

What is API 게이트웨이

API 게이트웨이는 API 클라이언트와 서비스 사이에 프록시 처럼 위치하여, 클라이언트로 부터 온, API 요청을 받아서, 서비스로 라우팅 하는 역할을 한다. 

각각의 서비스에서 구현해야 하는 기능을 API 게이트웨이단으로 통합함으로써, 서비스 개발을 간편하게 할 수 있고, 메세지 포맷 변경이나, 플로우 컨트롤과 같은 고급 기능을 사용하여, 기존 API 호출에 추가적인 기능을 더할 수 있는 유연성을 더할 수 있게 된다.


여러가지 기능이 있겠지만, 크게 아래와 같이 5가지로 나눠볼 수 있다.

  • 인증

  • 모니터링,로깅

  • 플로우 컨트롤

  • 메시지 변경

  • 오케스트레이션(매쉬업)





<출처 : 마이크로소프트 애저 홈페이지>


인증

API를 호출할때, API 호출에 대한 인증을 수행한다. 서버간의 API 통신일 경우에는 간단하게 API 키를 사용하는 방법등이 있고, 다수의 클라이언트 (모바일 단말, 웹 자바스크립트 클라이언트)의 경우에는 사용자 계정 인증 후에, JWT 토큰을 발급하는 방식이 있다. 

모니터링 & 로깅

API 호출에 대한 모니터링을 통해서 API 별 응답시간, 장애율,호출 횟수를 모니터링 할 수 있게 하고, 경우에 따라서 개별 API 호출을 로깅한다. 

Metering & Charging

API를 대외로 서비스 하는 경우, API의 호출량을 모니터링 해야 하는데, 이 양을 기반으로 해서 API 서비스 호출 횟수를 통제하거나 또는 유료 API의 경우에는 과금을 해야 하기 때문에, 대외로 서비스를 하는 오픈 API 플랫폼인 경우에는 이러한 기능이 필요하다. 

메시지 플로우 컨트롤

메시지 플로우 컨트롤은 클라이언트로 부터 들어온 메시지의 흐름을 바꾸는 방법인데, 예를 들어 같은 API라도 버전에 따라서 구버전과 새버전으로 트래픽을 9:1로 라우팅하는 카날리 배포 방식이라던지, 들어온 API를 클라이언트의 위치에 따라 미국이나,한국에 있는 서비스로 라우팅을 하는 등의 로직을 구현할 수 있다. 

Limiting (throttling)

조금 더 고급화된 구현방법으로는 Limiting 기법이 있는데, 특정 API에 대해서 정해진 양 이상의 트래픽을 받지 못하도록 하여, 서비스를 보호하거나 또는 유료 API 서비스인 경우 QoS (Quality Of Service)를 보장하기 위해서 특정 양까지만 트래픽을 허용하도록 컨트롤할 수 있다. 

메시지 변환

메시지 변환은 고급 기능 중의 하나인데, 헤더에 있는 내용을 메시지 바디로 붙이거나, 다른 API를 호출해서 응답메시지를 두 API를 합해서 응답을 해주는 기능등을 구현할 수 있다. 

프로토콜 변환

그외에도 서로 다른 프로토콜에 대한 변환이 가능한데, 예를 들어 클라이언트로 부터는 gRPC로 호출을 받고, API서버로는 REST로 호출한다던가. SOAP/XML 기반의 메시지를 REST로 변환하는 등의 기능 구현이 가능하다. 

호출 패턴 변환

API 서버가 큐를 기반으로한 비동기 메시지 처리 패턴일때, API 게이트 웨이에서 이를 동기화 처리 패턴으로 바꿔서, 클라이언트 입장에서는 동기로 호출을 하면, API 서버에서는 비동기로 호출하는 형태와 같이 호출 패턴을 변화시킬 수 있다. 

오케스트레이션(매시업)

API 클라이언트가 한번 호출을 할때, 동시에 여러개의 API를 호출하도록 API 게이트웨이에서 호출을 해주는 방식이다. 예를 들어 API 클라이언트가 “상품 구매" 라는 API를 호출 하였을때, API 게이트웨이가 “상품 구매" API 서비스를 호출하고, “상품 추천" 이라는 API도 호출해서, 클라이언트로 구매 완료 메시지와 함께 추천 상품 리스트를 한번에 리턴하는 방식이다. 


경량형 게이트웨이와 중량형 게이트웨이

API 게이트 웨이는 근래에 마이크로 서비스가 각광을 받으면서 언급되기 시작하고 있지만, 사실 API 게이트 웨이라는 기술 자체는 오래된 기술이다. API 게이트 웨이 이전에는 SOA 제품군의 일부로 ESB (Enterprise Service Bus)가 SOAP/XML 웹서비스 기반으로 이러한 역할을 해주었는데, 잘못된 구현 패턴을 사용해서 문제가 된 케이스가 많다. 예를 들어서 과도하게 오케스트레이션 기능을 사용하였을 경우 API 게이트웨이 자체에 부하가 걸려서 전체 API 서비스에 성능 문제를 야기 하거나, 또는 파일 업로드 요청을 API 게이트 웨이를 통해서 함으로써 게이트웨이의 부하때문에 성능 문제가 생기는 경우가 있었다. 

SOAP/XML에서 REST API로 오면서, API 게이트웨이도 이러한 문제를 피하는 패턴형식으로 API 게이트 웨이가 포지셔닝이 달라졌다. 사실 매시업이나, 메시지 라우팅, 메시지 변환등과 같은 기능들은 사실 사용되는 일이 그렇게 많지 않고, 클라이언트단에서 처리해도 충분하기 때문에, 이러한 고급 기능 보다는 API 인증, 로깅/모니터링 위주의 최소한의 기능만 가지면서 경량화된 형태로 배포 및 운영이 간편한 경량형 API 게이트 웨이들이 소개 되기 시작하였고, 반대로 오픈 API를 고객을 대상으로 제공하면서 메시지 변환이나, 과금등 고급 기능을 제공하는 중량형 API 게이트 웨이들도 꾸준히 제품들이 제공되고 있다.


이러한 제품들에 대한 명시적인 구분은 없지만, 필자의 기준으로 봤을때, 경량형 API 게이트 웨이는 Kong등을 들 수 있고, 중량형 API 게이트 웨이는 APIgee, MuleSoft 등을 들 수 있다. 


전통적으로 중량형 API 게이트웨이의 아키텍쳐 구조는 API 게이트웨이가 클러스터 형태로 배포 된 후에, 그 뒤에 API 서버들이 배포되는 형태라면, 경량형 API 게이트웨이는 nginx나 node.js와 같은 가벼운 프록시 서버로 배포하고, 용량이 필요하다면 개별의 인스턴스들을 스케일링으로 늘리는 방법을 사용한다. 근래에는 중량형 API 게이트 웨이도 이러한 구조를 많이 참고해서 구조를 개선하고 있다. 

쿠버네티스와 API 게이트 웨이

이러한 API 게이트웨이들이 쿠버네티스의 등장과 함께 주목 받으면서, 쿠버네티스 지원을 넓혀나가고 있는데, 이 과정에서 흥미로운 아키텍쳐 구성을 보인다. 쿠버네티스는 이미 Service라는 리소스를 통해서 마이크로 서비스를 정의할 수 있고, Service를 묶어서 로드밸런싱을 하는 Ingress라는 리소스를 가지고 있다. 즉 Ingress는 Service간의 라우팅을 할 수 있는 일종의 초경량 API 게이트웨이로써의 기능을 가지는 구조인데, API 게이트웨이의 쿠버네티스 연동은, 새롭게 애플리케이션을 배포하고 설정하는 방식이 아니라 쿠버네티스 리소스 자체에 API 게이트웨이를 녹이는 방식으로 접근하고 있다.


아래 Kong API 게이트웨이의 구조를 보면, Kong 전용으로 컨테이너를 배포하지 않고, Kong API 게이트웨이용 Ingress를 정의해서 사용자가 Ingress를 사용하게 되면 API 게이트웨이를 사용할 수 있게 하였고, 메시지 변환이나 기타 기능이 필요할 경우 이를 CRD(Custom Resource Definition) 로 미리 등록해놔서 이를 사용하도록 하고 있다. 



<Kong API 게이트 웨이 아키텍처 출처  > 


구글의 Apigee의 경우에는 Apigee Hybrid라는 이름으로 Kubernetes를 지원하는데, 구조는 Istio Ingress를 앞단에 둬서 라우터로 이용하고 API 게이트웨이에서 처리하는 각종 로직을 Ingress 뒤에 Pod(아래 그림 4번)로 배포하여 기능을 수행하도록 하고 있다. 

API 호출을 통과 시키는 프록시는 이렇게 단순화 시키고, 관리 콘솔은 구글 클라우드로 위치 시켜서 운영을 최대한 단순화 시켰다. 


<출처 : 구글 apigee hybrid 문서 > 

구글의 API 게이트 웨이 - Cloud Endpoint

구글의 Cloud Endpoint는 경량형 API이다. 

기본적으로 nginX로 배포되서 프록시 처럼 동작하며, 기능은 API 인증과 모니터링/로깅정도 밖에 없지만 구조와 기능이 단순하기 때문에 사용이 편리하며, 또한 nginX 기반의 배포 방식으로 인해서 구글 클라우드 뿐만 아니라, 다른 클라우드나 ON-PREM에도 사용이 가능하다는 장점이 있다. 


구조는 다음과 같이 되어 있다.



<그림. Cloud Endpoint ESP 아키텍쳐 / 출처 >


ESP는 Cloud Endpoint의 Proxy, 즉 nginX를 이야기 한다. 프록시는 실제로 쿠버네티스 클러스터에 배포되고, 모니터링과 로깅, 컨트롤러는 구글 클라우드의 콘솔을 이용하게 된다. 

쿠버네티스에 배포하는 형태는 다음 그림과 같다. 

애플리케이션 컨테이너와 함께, 같은 Pod로 패키징 되고, ESP에서는 애플리케이션으로 트래픽을 localhost로 포워딩한다. 


<그림. ESP의 쿠버네티스 배포 형태 >


이런 구조를 가지기 때문에, Ingress, Istio 등 다른 쿠버네티스 플랫폼들과 유연하게 통합이 된다. 

API 인증은 여러가지 방법을 지원하는데, Firebase authentication, Google ID,SAML(SSO) 방식으로 사용자를 인증한후에, API 키(JWT)를 발급하는 방법이나, 서버간일 경우 Service Account를 사용하는 방법 또는 단순하게 API KEY를 사용하는 방법이 있고 또는 Custom 인증을 구현하여 JWT 토큰으로 인증할 수 있다. 인증 방식은 이 문서를 참고하면 된다.

로깅/모니터링

로깅과 모니터링은 End Point 콘솔에서 볼 수 있으며, 아래와 같이 서비스 단위로 응답 시간과 에러율등을 출력해준다


OPEN API (Swagger) 기반 포탈

그리고 중요한 기능중의 하나인데, API 스펙 문서를 포탈 형태로 보여준다. Swagger 문서 형태로 작성을 하면 아래와 같이 독립된 웹사이트 형태로 API 스펙 문서를 보여준다.


<그림. Cloud endpoint developer portal / 출처


멀티/하이브리드 클라우드

마지막으로, Cloud End Point는 ngnix 기반으로 배포가 가능하기 때문에, 구글 클라우드 뿐 아니라 타 클라우드나 온프렘 데이타 센터내에도 프록시(ESP)를 배포해서 사용하는 것이 가능하다. 


참고 문서


본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

댓글을 달아 주세요

MSA 아키텍쳐 구현을 위한 API 게이트웨이의 이해 #1

조대협 (http://bcho.tistory.com)


MSA(마이크로 서비스 아키텍쳐, 이하 MSA)와 함께 근래에 떠오르고 있는것이 API 게이트 웨이이다. API 게이트웨이는 API서버 앞단에서 모든 API 서버들의 엔드포인트를 단일화하여 묶어주고 API에 대한 인증과 인가 기능에서 부터 메세지에 따라서 여러 서버로 라우팅 하는 고급기능 까지 많은 기능을 담당할 수 있다.

API 게이트웨이의 시작은 MSA가 SOA(서비스 지향 아키텍쳐)에서 시작한것 처럼 ESB (Enterprise Service Bus)에서 부터 시작 되었다. 그래서 ESB의 대부분의 컨셉을 많이 승계했는데, ESB의 실패와 단점을 보완해서 만들어진 사상이 API 게이트웨이이다. ESB가 SOAP/XML 웹서비스 기반의 많은 기능을 가지는 구조였다면, API 게이트 웨이는 JSON/REST 기반에 최소한의 기능을 처리하는 경량화 서비스 이다. 그리고 ESB는 SOA의 사상에서 개념적으로 탄생한 솔루션이라면, API 게이트 웨이는 ESB의 실패와, MSA, REST 구현 사례를 통해서 필요에 의해서 탄생한 솔루션이기 때문에, 그 실용성이 차이가 난다.


MSA에 대한 개념은 http://bcho.tistory.com/948 를 참고하기 바라며, 이 글은 API 게이트웨이에 대한 바른 이해를 돕고, API 게이트웨이를 도입하고자 하는데 필요한 내용을 서술하고자 한다.


API 게이트웨이의 주요 기능


먼저 API 게이트웨이의 주요 기능에 대해서 알아보자


인증/인가에 관련된 기능


API 게이트웨이의 가장 기본적인 기능은 API 에 대한 인증과 인가 관련 기능이다. 인증은, API 를 호출하는 클라이언트에 대한 identity(신분)를 확인 해주는 기능이고, 인가는 클라이언트가 API를 호출할 수 있는 권한이 있는지를 확인해주는 기능이다. 

쉽게 이야기 하면 내가 페이스북 계정을 가지고 있는 사용자가 맞는지 , API 호출시 어느 권한 (일반사용자, 관리자 권한)까지 호출할 수 있는지를 판단하여 API 호출을 허가하는 기능이라고 볼 수 있다.


API 토큰 발급


인증 인가를 거칠때 마다 매번 사용자의 인가/인증 절차를 거치기는 불편하다. 사용자로 부터 매번 사용자 ID와 비밀 번호를 받기는 번거롭고, 그렇다고 사용자 ID와 비밀 번호를 저장해놓는 것은 해킹의 빌미를 제공한다.

그래서 보통 사용하는 방식이 토큰이라는 방식을 사용하는데, 사용자 인가가 끝나면, 사용자가 API를 호출할 수 있는 토큰을 발급해준다. API 서버는 이 토큰으로 사용자의 identity 와 권한을 확인한후, API 호출을 허가해준다.


API 게이트 웨이는 클라이언트를 인증한 후, 이러한 API 토큰을 생성 및 발급해주는 역할을 한다.


 

<그림. 일반적은 토큰 발급 절차>


토큰 발급을 위해서는 먼저 클라이언트를 인증해야 한다.


클라이언트를 인증하는 방법은 가장 간단하게 사용자의 id와 password를 넣는 방법에서 부터, 공인 인증서를 이용하는 방법, 지문이나 OTP (One time password) 등을 이용하는 방법등 다양한 방법이 있다. 각 보안 요건에 요구 되는 다양한 방식에 따라서 클라이언트를 인증한 후에, apitoken을 발급하게 된다.


이때, 클라이언트에 대한 인증은 직접적으로 API 게이트웨이가 하지 않고 뒷단에 있는 인증 서버가 이를 수행하는데, 간단하게는 내부 계정 관리를 위한 Active Directory, LDAP 또는 RDBMS등이 될 수 도 있으며, 외부 인증 서버로는 예를 들어서 온라인 게임 서비스에 가입할때, 페이스북 계정을 사용하는 경우, 온라인 게임 서버가 페이스북에 이 사용자의 인증을 요청하고, 페이스북이 인증을 해주면 온라인 게임서버가 apitoken을 발급해주는 흐름등을 들 수 있다.


그래서 API 게이트웨이의 중요한 기능중의 하나는 다양한 인증 서버와 연계가 가능한 것이 좋다.


이렇게 발급된 토큰을 API를 호출할 수 있는 권한 정보와 연관이 되는데, 이 권한 정보를 토큰 자체에 저장하느냐 또는 서버에 저장해놓느냐에 따라서 두 가지 종류로 나눌 수 있다.

토큰 자체가 이러한 정보를 갖는 형태를 클레임 기반의 토큰 (Claim based token)이라고 하는데, 근래에 유행하는 JWT (JSON Web Token)이나 SAML 토큰등이 이에 해당한다. 예를 들어 토큰 자체가 아래와 같은 정보를 가지고 있는 형태라고 생각하면 된다. 


{

“name”:”Terry”,

“role”:[“admmin”,”enduser”]

“org”:”petstore”

}

<그림. 클레임 기반의 토큰 예>

JWT가 이러한 형태의 토큰인데 JWT에 대한 자세한 설명은 http://bcho.tistory.com/999 와 http://bcho.tistory.com/1000 를 참고하기 바란다.

클레임 기반의 토큰이 아닌 경우, 이러한 클레임 정보를 서버에 저장해놓게 되는데, 클라이언트로는 unique한 string만을 리턴해주는 경우이다.

 


<그림. 서버에 토큰을 저장하는 경우>


이 서버 기반의 토큰이 현재 일반적으로 가장 많이 사용되는 형태인데, token에 연관되는 정보가 서버에 저장되기 때문에 안전하고, 많은 정보를 저장할 수 있으며, token에 대한 정보를 수정하기가 용이하다. 그러나 서버단에서 별도의 토큰 저장소를 유지해야 하기 때문에 구현 노력이 더 높게 든다. 토큰은 매 API 호출마다 정보를 가지고 와야 하기 때문에, DBMS와 같은 FILE IO 기반의 저장소 보다는 redis, memcached와 같이 메모리 기반의 고속 스토리지를 사용하는 것이 좋다.


클레임 기반의 토큰은 이러한 토큰 저장소가 필요 없다는 장점이 있어서 구현은 용이하지만, 토큰 자체에 클레임 정보가 들어가 있기 때문에, 토큰의 길이가 커지기 때문에 일정 양 이상의 정보를 담기가 어려우며, 한번 발급된 토큰은 변경이 어렵다. 예를 들어 role:admin으로 관리자 권한으로 발급된 토큰은 서버쪽에서 파기가 불가능하기 때문에 토큰 통제가 어렵다는 단점을 가지고 있다. 그래서, 클레임 기반의 토큰을 사용할때는 토큰의 유효기간을 둬서 반드시 강제적으로 토큰을 주기적으로 재발급 받도록 하는 것이 좋다.


엔드포인트별 API 호출 인증


Apitoken이 발급되었으면, 클라이언트는 이 apitoken을 이용하여 API를 호출하는데, 이 때 API 게이트웨이는 apitoken을 검증함으로써 API 호출을 승인할지 여부를 결정한다.

서버에 토큰 정보가 저장되는 형태의 경우 매 API 호출 마다 해당 apitoken을 가지고 연관 정보를 토큰 저장소로 부터 읽어와서 비교한후, 그 정보를 기반으로 API 호출 가능 여부를 결정한다.

 




<그림. Apitoken을 이용한 API 호출 인증>


클레임 기반의 토큰의 경우에는 이러한 작업이 없이 그냥 API 게이트 웨이에서 apitoken을 까보고, 그 안에 있는 내용을 가지고 API 호출 가능 여부를 결정한다.


이렇게 api token으로 인증을 하는 방법이 일반적인 방법이지만, 서버대 서버간의 통신은 내부 서버의 경우 별도의 인증 없이 API 를 제공하는 경우도 있고, 외부 서버와의 통신은 특정 ip 주소와 통신을 허용 하거나 높은 보안을 요구하는 경우 양방향 SSL등의 인증 방식을 사용함으로써 apitoken없이도 API 호출을 인증하는 방법도 있다..

이렇게 각각의 클라이언트나 서비스 별로 제공되는 엔드포인트에 대해서 API 인증 방식이 다르기 때문에, API 게이트웨이에서는 각 엔드 포인트 별로 다양한 형태의 인증 방식을 제공해야 한다. API 게이트를 이용하여 다양한 엔드포인트를 통해 서비스를 제공하는 방법은 뒤에서 다시 설명하도록 한다.


엔드포인트별 API 요청 인가


인증(Authentication)과 인가(Authorization)은 다른 의미를 갖는데, API를 호출 하는 것이 Terry가 맞다는 것을  확인 해주는 것을 인증이라고 한다면, 이 Terry가 이 API를 호출할 수 있는 권한이 있는 것을 확인해주는 것이 인가(Authorization)이다. 쉽게 생각하면, 일반 사용자용 API와 관리자용 API를 생각하면 이해가 쉽다.


이렇게 권한을 제어하는 방식은 여러가지가 있는데, 각 개별 권한을 토큰에 부여 하는 방식과 역할(ROLE) 기반으로  권한을 부여하는 방식이 대표적이다.


개별 권한을 토큰에 부여 하는 방식은 다양한 권한 정책을 세밀하게 관리할 수 있다는 장점을 가지고 있다.

 


<그림. 토큰에 역할을 부여하는 방식>


토큰에 제한적으로 권한을 부여할 수 있다는 장점을 가지고 있는데, 페이스북이 이런 형태의 권한 통제 모델을 사용한다. 

https://developers.facebook.com/docs/facebook-login/permissions/v2.2?locale=ko_KR

에 보면 api 토큰에 연동할 수 있는 권한 리스트들이 있는데, 페이스북의 써드파티 애플리케이션을 보면, 페이스북의 API의 권한을 일부 요청 하는 형태로 토큰에 권한을 연결한다.


그렇지만,이 방식의 경우에는 권한의 종류가 많을 경우, 관리가 어려워 지고 복잡해지기 때문에, 일반적으로 역할(ROLE)기반으로 권한을 관리 하는 방식을 많이 사용한다.


직접 권한을 토큰에 연결하는 것이 아니라, 역할이라는 개념을 두고, 역할별로 권한을 연결한 다음에, 이 역할을 토큰에 부여하는 개념이다 쉽게 이야기 하면, 관리자용 기능과 일반 사용자용 기능을 분리한 다음에, 관리자나 일반 사용자와 같은 역할(ROLE)을 토큰에 부여하는 방식이다. 이를 RBAC (Role Based Access Control)이라고 한다.


이 RBAC 기반으로 하면, 통제 해야 하는 권한의 숫자가 줄어들기 때문에, 다음과 같이 엔드포인트를 나눠서 권한 접근 제어가 가능하다. (예를 들어 총 권한이 100개가 있다고 했을때, 이를 관리자용 기능과 일반 사용자용 기능으로 나누어 버리면, 관리해야 하는 두개의 권한 집합을 나뉘어 진다.) 


이런 경우 관리자용 API 엔드포인트(/service/admin), 일반 사용자용 API 엔드포인트(/service/users) 두 개로 나눈 다음에, apitoken에 권한을 admin,user 두가지 종류로 정의한 후에, /service/admin 엔드포인트에서는 api token이 admin 권한이 있을 경우에만, 호출을 허용하도록 하면 된다. 


 

<그림. 역할(ROLE)별로 엔드포인트를 나눠서 권한 인가를 하는 구조>

API 라우팅


API 게이트웨이에서 다음으로 유용한 기능중의 하나가 API 호출을 라우팅 하는 기능이다. 같은 API라도 사용하는 서비스나 클라이언트에 따라서 다른 엔드포인트를 이용해서 서비스를 제공하거나, 데이타 센터가 여러개일때, 데이타 센터간의 라우팅등을 지원하는 기능이다. 주요 기능들을 보면 다음과 같다.


백엔드 API 서버로의 로드 밸런싱


가장 기본적인 기능으로는 로드밸런서 기능이다. API 게이트 웨이 뒷단에 다수의 API 서버가 있다고 할때, 여러개의 API 서버로 부하를 분산하는 기능이 필요하다.

 


<그림. API 게이트 웨이를 통한 API 서버로의 로드 밸런싱>


단순하게 Round Robin 방식으로 부하를 분산하는 기능뿐만 아니라, 각 서버 하드웨어에 따라 부하를 가중치를 줘서 분산하는 기능등을 고려해볼 수 있겠고, 무엇보다 중요한 기능은 API 서버가 장애가 났을때 이를 감지해서 로드 밸런싱 리스트에서 빼고, 복구 되었을때 다시 로드 밸런싱 기능에 넣는 기능들이 필요하다.


단순하게, HA Proxy와 같은 L4의 기능처럼, 뒷단의 서버가 살아 있으면 부하를 보내고 죽었으면 부하를 안보내는 기능에서 부터, 고급 기능으로는 API 서버가 Hang up (멈춤)에 걸렸을 때 이를 인지해서 부하를 안보내는 기능등을 고려해볼 수 있다. 이러한 고급 기능은 API 서버의 애플리케이션 상태를 인지해야 하기 때문에 단순히 IP 포트가 살아 있음을 가지고 판단 하는 것이 아니라 쓰레드 수, 응답 시간등으로  서버의 장애 상태를 판단해야 한다.  


서비스 및 클라이언트 별 엔드포인트 제공


또 다른 유용한 기능중의 하나는, 같은 API를 여러개의 엔드포인트를 통해서 서비스를 제공할 수있다는 점인데, 하나의 시스템이 다양한 서비스나, 다양한 클라이언트등으로 서비스를 제공할때, 각각 다른 서비스 별 또는 클라이언트 별로 다른 엔드포인트를 제공할 수 있다.

예를 들어서 IOT 플랫폼 서비스가 있다고 하자. 이 플랫폼은 REST API를 제공하는데, 이를 통해서 센서로 부터 데이타를 수집해서 분석하는 시스템이라고 가정하자.

이 시스템은 선박용 서비스, 비행기용 서비스, 차량용 서비스를 지원한다고 가정하자.

각 서비스별로 API의 특성이나 노출되는 API가 다소 다를 수 있는데, 각 서비스 별로

  • 선박용 /ships/
  • 비행기용 /airplanes/
  • 차량용 /cars/

라는 식으로 각각의 다른 엔드 포인트를 제공할 수 있다.

그리고, 이 서비스에서는 센서로 부터 데이타를 수집하는 시나리오와, 관리자가 웹을 통해서 시스템을 관리하기 위한 API가 있다고 가정하면, 앞의 API는 다음과 같이 클라이언트의 종류에 따라서 분리 될 수 있다.


  • 선박 센서용 /ships/sensors/, 선박 관리자 웹 /ships/admin
  • 비행기 센서용 /airplanes/sensors/, 비행기 관리자용 /airplanes/admin
  • 차량 센서용 /cars/sensors, 차량 관리자용 /cars/admin

그리고 각각의 엔드포인트 별로 노출(expose)하는 API를 다르게 할 수 있다.

 


< 그림. API를 엔드포인트 별로 다르게 노출>


API 게이트 웨이는 API 서버가 공통적인 API를 가지더라도, 각 서비스나 클라이언트 타입에 따라서 각각 다른 API 를 선별적으로 서비스 할 수 있도록 해준다.


※ 실제로 멀티 서비스를 제공하는 플랫폼형태의 경우에는 이 기능이 매우 유용하다.특히 같은 API라도 클라이언트의 종류에 따라서 인증 방식이 다를 수 있고 보안 메커니즘이 다를 수 있다.


메세지 또는 헤더기반 라우팅


라우팅에서 유용한 기능중의 하나는 메세지 내용을 기반으로 하는 라우팅이다. 예를 들어 그림과같이 HTTP 헤더에 country code가 있을 경우, country code에 따라서 유럽에 있는 API를 호출하거나 또는 미국에 있는 API 서버를 호출할 수 있도록 Routing을 할 수 있다.

 


<그림. 메세지 기반의 글로벌 라우팅 예시>


특히 글로벌 단위로 배포되는 시스템인 경우 각 데이타 센터간에 메세지를 라우팅 시키는데 유용하게 사용할 수 있다. 위의 예에서 처럼, 특정 데이타 센터로 조건에 따라 라우팅을 할 수 도 있고, 또는 중앙 집중형 시스템의 경우, 각 지역에 API 게이트 웨이를 두고, 클라이언트는 가까운 API  게이트 웨이를 호출하지만, 중앙 데이타 센터에만 있는 API 서버의 경우 중앙 데이타 센터로 호출을 라우팅 할 수 있다.


데이타 복제가 필요할 경우, 미국에 있는 API 게이트웨이로 호출하면 API 게이트 웨이가 미국 API서버와, 유럽 API 서버를 동시에 호출해서, 업데이트성 트렌젝션을 모든 데이타 센터에 복제함으로써 API를 통한 데이타 복제가 가능해진다.

라우팅에 있어서 고려해야할 사항은 먼저 메세지에 대한 라우팅인데, REST API를 기준으로 설명하면, REST API는 HTTP URL,HTTP Header,HTTP Body 3가지로 구분이 된다.


메세지를 기반으로 라우팅을 하기 위해서는 API 게이트 웨이가 이 메세지를 파싱해야 한다.

예를 들어 country_code가 HTTP Body에 JSON으로 다음과 같이 들어가 있다고 가정하자


{

“country_code”:”US”

  :

}


이 경우 이 API 호출에 대해서 라우팅 정보를 추출하기 위해서 매번 HTTP Body에 있는 JSON을 API 게이트웨이가 파싱해서 열어봐야 한다. 이는 빠르게 메세지가 통과해야 하는 API 게이트웨이의 역할에 많은 부담을 준다. 만약에 이러한 라우팅 정보를 HTTP Header로 옮긴다면, HTTP Body는 파싱하지 않고, Header만 파싱한후, Body 정보는 라우팅되는 서버로 그냥 포워딩만 해도 된다.


그래서 메세지 기반의 라우팅을 사용할 때는 이러한 파싱에 대한 오버헤드를 잘 고려하고, 가능하면, HTTP URL이나 HTTP Header에 라우팅 필드를 넣는 것이 좋다. 


부득이하게, HTTP Body에 있는 내용으로 라우팅을 해야 하는 경우에는 호출 빈도가 적은 API인 경우 API 게이트웨이에서 담당하고, 다른 경우에는 별도의 게이트웨이 인스턴스(프로세스)로 분리를 하거나 뒷단의 API서버가 라우팅을 하도록 하는 것도 하나의 방안이 된다.


공통 로직 처리


API 게이트웨이는 특성상 모든 API 서버 앞쪽에 위치 하기 때문에, 모든 API 호출이 이 API 게이트를 거쳐간다. 그렇기 때문에, 모든 API 가 공통적으로 처리해야 하는 공통 기능이 필요할 경우 이러한 공통 기능을 API 게이트웨이로 옮기게 되면 별도로 API 서버에서 이러한 기능을 개발할 필요 없이 비지니스 로직 자체 구현에만 집중할 수 있게 된다.

아래 그림은 각 API 서버에서 인증과, 로깅에 관련된 로직을 API 게이트웨이로 이전한 구조이다.

API 로깅이나 인증은 전체 시스템에 대해 공통된 기능으로, 공통 계층에서 처리하게 되면 개발 중복을 줄일 수 있는 장점뿐만 아니라, 표준 준수가 더 쉽다는 장점을 가지고 있다. 

 


<그림 API 게이트웨이를 이용하여 공통 로직을 API 서버에서 API 게이트웨이로 이전한 구조>


메디에이션 기능 (Mediation)


메디에이션이란, 한글로 “중재”또는 “조정” 이라는 의미를 갖는데, API서버에서 제공되는 API가 클라이언트가 원하는 API 형태와 다를때, API 게이트웨이가 이를 변경해주는 기능을 이야기 한다. 구체적인 기능을 보자


메세지 포맷 변환 (Message format transformation)


메세지 포맷을 변환하는 기능이란, JSON으로 된 요청(Request) 메세지가 들어왔을때, 이를 API 서버로 보낼때 변환 해서 보내거나, 또는 API 서버에서 생성된 응답을 클라이언트에 리턴할때 변경해서 보내는 기능을 의미한다.


예를 들어보자, 아래와 같이 terry의 연봉(salary) 정보를 구하는 API가 필요하다고 하자. 그런데, 시스템에는 연봉 정보만 주는 API는 없고, 전체 사용자 정보를 리턴하는 API만 있는 상황이다.


이런 경우, API 게이트 웨이를 통해서 /users/salary라는 새로운 API를 제공하고, 이를 기존에 전체 사용자 정보를 주는 /users/details라는 API로 라우팅 한다. /users/details에서 사용자 정보를 뽑았을때, 클라이언트에게 응답을 줄때는 API 게이트웨이에서 아래 그림과 같이 name과 salary 정보만 뽑아서 리턴하도록 한다.

 


<그림. 메세지 포맷 변환의 예시>


일단 간단한 기능으로 구현이 가능하기 때문에 서술은 해놨지만, 그다지 권장하고 싶지 않은 기능이다. 메세지 포맷이 변환이 된다면, 차라리 필요한 포맷에 맞는 API를 따로 뽑아 내는 것이 났지 않나 싶다.


프로토콜 변환 


다양한 서비스나 클라이언트를 지원하게 되면, 클라이언트나 서비스별로 다른 통신 프로토콜을 사용해야 하는 경우가 있다. 웹에서는 JSON기반의 REST가 많이 사용되지만, 배나 비행기에 사용되는 센서들의 경우에는 REST도 무겁기 때문에 바이너리 기반의 경량 프토토콜을 사용하거나, 또는 예전 엔터프라이즈 시스템의 경우 XML 기반의 웹서비스를 이용할 수 도 있다.


이렇게 다양한 타입의 프로토콜을 지원하기 위해서, 각 서비스들이 새롭게 구현을 하는 것이 아니라 API 게이트웨이 계층에서 프로토콜 변환을 통하여, 같은 API를 다른 프로토콜로 서비스 할 수 있도록 할 수 있다.

 


<그림. API 게이트 웨이를 통한 프로토콜 변환>


실제로 유용한 기능인데, 내부 API는 REST가 아니라 페이스북 Thrift나 구글의 Protocol Buffer로 구현을 하고, 외부에 제공하는 API는 API 게이트 웨이단에서 REST 로 변경해서 서비스 하는 구조를 이용하면, 내부 API 성능을 올리고, 외부로는 REST API로 서비스 함으로써 범용성을 확보할 수 있다. (실제 사례가 있었다.)


또한 근래에 M2M이나 IOT (Internet of things)와 같은 개념이 활성화 되면서, HTTP REST 뿐 아니라 기존의 센서에서 통신에 사용되는 다양한 프로토콜을 지원하여 백엔드 API 서버의 프로토콜로 맞춰줘야 하는 필요가 점점 증대되고 있다.


메세지 호출 패턴 변환 (Message Exchange Pattern : MEP)


메세지 호출 패턴, 보통 MEP(Message Exchange Pattern)라고 하는데, 동기,비동기 호출과 같은 API를 호출하는 메세지 패턴을 정의한다.

API 게이트웨이의 좋은 기능중의 하나가 이 MEP를 변경할 수 있다는 건데, 쉽게는 Async API호출을 Sync 호출로 바꿔 준다거나, 하나의 API 호출을 여러 데이타 센터로 복제 해준다거나 하는 형태의 메세징 패턴을 변화 시킬 수 있다.

 


<그림. 비동기 호출을 API게이트웨이를 통해서, 동기 호출로 변경한 구조>


위의 그림의 예제는 로그를 수집하는 시스템에 대한 구조이다.뒷단의 로그저장 API 서버가 대용량 트래픽에 대한 대응 능력이 없을때, API 게이트 웨이에서 큐를 이용해서 API 요청을 받고 (1), 바로 클라이언트에 ACK를 준후에, 메세지큐 연동을 이용하여 메세지를 저장한후, 로그 저장 API 서버의 성능에 맞게 흘려주는 방식이다. 클라이언트 입장에서는 동기 호출이지만 실제 메세지 흐름은 큐를 이용한 비동기 구조로 변경되었다.


어그레게이션 (aggregation)


SOA에서는 Orchestration(오케스트레이션)이라고 불렀는데, 여러개의 API를 묶어서 하나의 API로 만드는 작업을 이야기 한다. 예를 들어서, 계좌 이체를 한다고 했을때,


A은행에서 잔액 확인

A은행에서 인출

B은행으로 입금


하는 3개의 API 호출을 하나의 API 인 POST transfer(인출계좌,입급계좌,금액)으로 구현한다고 하자.이를 API 게이트웨이에서 구현 하면 다음과 같은 형태로 구현할 수 있다.

 


<그림. API 게이트 웨이를 이용한 API Aggregation>


대부분의 API 게이트 웨이 제품들은 이러한 aggregation을 할 수 있는 일종의 워크플로우 엔진과 유사한 기능들을 가지고 있다.


 


<그림. Apigee 제품의 워크플로우 저작도구 화면>


이러한 aggregation 기능이 언뜻 보면 좋아보이지만, 하나의 플로우에서, 여러 API를 호출해야 하고, 비지니스 로직을 수행하면서 실제로 API 메세지 BODY까지 파싱해야 하기 때문에, API 게이트 웨이 입장에서는 부하가 매우 크다. 


MSA 의 전신인 SOA에서 API 게이트웨이와 유사한 역할을 했던 ESB역시 이러한 aggregation (ESB에서는 보통 오케스트레이셔이라고 함)을 남발해서, ESB의 성능이 떨어져서 시스템 개발이 실패하는 아키텍쳐를 많이 봤다.

그래서 본인의 경우에는 이러한 무거운 aggregation 로직은 별도의 Mediator API 서버라는 계층을 만들어서, API 게이트웨이 밖에서 따로 하는 방법을 권장한다.


아래 그림과 같이 여러 API를 조합하는 목적의 API 서버를 별도로 둬서, 이러한 기능을 API 게이트웨이에서 제거한다.

 


<그림. API aggregation을 API 게이트웨이에서 Mediation API 서버로 분리한 구조>


aggregation 로직을 API 게이트웨이 안에 넣으면 확실하게  게이트웨이가 받는 부하량은 올라간다. 설치형 API 게이트웨이의 경우, 이는 추가적인 하드웨어 박스를 더 구매하고, 상용 API 게이트웨이의 경우 라이센스를 더 구매해야 한다는 것을 의미하기 때문에, Mediation API 서버 계층을 사용하는 것을 권장한다.


클라우드형 API 게이트웨이의 경우, 호출 수로 과금을 하기 때문에 aggregation 로직을 API 게이트웨이에 넣는 방안을 고려해볼 수 있으나, aggregation 로직이 게이트웨이 안에 있으면 디버깅이나 테스팅이 쉽지 않기 때문에, 이를 적절히 고민한 후 판단해서 aggregation 로직의 위치를 결정해야 한다.


로깅 및 미터링


API 게이트웨이의 비기능적인 요건으로 중요한 기능이 로깅과 미터링이다. 


API 호출 로깅


앞서 공통 로직 처리 부분에서도 언급하였지만, API 호출시 API 게이트웨이는 공통적으로 호출되는 부분인 만큼 모든 로그를 중간에서 수집하기가 가장좋다.


근래의 애플리케이션 아키텍쳐가 클라이언트와 서버간의 통신이 모두 API를 기반하는 형태로 변경이되어감에 따라 API 호출 패턴을 분석하면 사용자의 사용 패턴을 분석해낼 수 있기 때문에, 빅데이타 영역과 연계하여 API 호출 로그는 아주 중요한 자산으로 다루어지고 있다.


또한 API 호출 로그는 차후 문제가 발생하였을때, 문제를 추적하기 위한 중요한 자료로 사용된다. (Audit: ‘감사’의 목적) 그래서, API 로그 수집은 단순 분석 목적뿐 아니라, 향후 감사 목적용으로도 저장되어야 한다.


근래에 출시되고 서비스되는 클라우드형 API 게이트웨이의 경우에는 특히나 이 API에 대한 로그 분석 기능을 강화해서 출시되고 있다.

 


<그림. Apigee.com의 API 모니터링>


API 미터링 & 차징 (Metering & Charing)


API 미터링과 차징은 유료 API 서비스를 위한 기능으로,  미터링은 과금을 위한 API 호출 횟수,클라이언트 IP, API 종류,IN/OUT 용량등을 측정 기록하는 서비스이고,

차징은 미터링이 된 자료를 기반으로 하여, API 서비스 사용 금액을 금액 정책에 따라서 계산 해내는 서비스이다. 

대부분의 SNS 오픈 API 서비스는 무료인 경우가 많지만, 구글 API 의 경우에도, 특정 호출 횟수(/일)을 넘어가면 과금등을 하도록 되어 있다.


QoS 조정 (Quality of service)


마지막으로 QoS 조정 기능이란, API 서비스를 클라이언트 대상에 따라서 서비스 레벨을 조정하는 기능이다.

유료 서비스가 있는  API 서비스라고 가정할때, 무료 사용자의 경우 1일 1000건으로 호출횟수를 제한 한다거나, 전송 용량이나, 네트워크 대역폭을 유료/무료 사용자에 따라 다르게 적용하는 것과 같은 기능을 QoS 기능이라고 한다.

유료 서비스인 경우만 아니라, 플랫폼 차원에서 다양한 클라이언트나 다양한 서비스로 API 를 제공하는 경우, 각 클라이언트나 서비스에 따라서 이 QoS를 조정하는 기능은 유용하게 사용될 수 있다. 특정 서비스나 클라이언트가 폭주하여 API를 과도하게 사용하여 다른 서비스들이 API를 사용할 수 없게 한다던가 그런 문제를 미연에 예방할 수 있다.


결론


지금까지 간단하게나마 API 게이트웨이의 대략적인 기능에 대해서 알아보았다. 다음에는 API 게이트웨이 기반 아키텍쳐를 확장하는 방법과 API 게이트웨이의 안티패턴과 설계 방법론 등에 대해서 소개하도록 한다.


참고

API 플랫폼의 이해 http://bcho.tistory.com/808

대용량 분산 시스템을 위한 마이크로서비스 아키텍쳐 http://bcho.tistory.com/948




본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.

댓글을 달아 주세요

  1. common 2015.03.03 09:26  댓글주소  수정/삭제  댓글쓰기

    귀찮은 일들을 여기서 다 해주는 구조네요. 마이크로 서비스를 원활하게 동작하기 위한 메인 콘트롤러 같아 보이는 구조인데 게이트웨이 자체의 부하조절이 핵심 요구사항 이지 않을까 싶습니다.

    • 조대협 2015.03.03 10:23 신고  댓글주소  수정/삭제

      부하 조절 기능 보다는, 게이트웨이가 부하를 덜 받게 설계 하는게 중요하겠져.
      그리고 API 에 대한 부하조절도 위에 언급한것 처럼 QoS 컨트롤 기능으로 주요 기능으로 구현되기도 합니다.
      :)

  2. yacuri 2018.08.08 10:36  댓글주소  수정/삭제  댓글쓰기

    글 잘 읽었습니다.

    API 게이트웨이 관련 많이 쓰이는 상용 솔루션으로는 무엇이 있을까여?

  3. 바지년 2019.10.27 12:02  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 좋은 글 감사합니다.
    API GATEWAY 하나에서 많은 일을 처리하다 보면, API GATEWAY 자체에 대한 트래픽이 몰려서 부하가 올 것 같은데, 이 경우는 어떻게 처리할 수 있으려나요? api gateway를 여러 대 두고, 이것을 위한 로드 밸런서가 있거나.. 해야 하려나요