API Gateway를 사용한 API 요청 체이닝
May 23, 2023
통합해야 할 API의 수가 증가함에 따라 API 상호작용의 복잡성을 관리하는 것이 점점 더 어려워지고 있습니다. API Gateway를 사용하면 API 호출 시퀀스를 생성하여 API 워크플로우를 더 작고 관리하기 쉬운 단계로 나눌 수 있습니다. 예를 들어, 온라인 쇼핑 웹사이트에서 고객이 제품을 검색할 때, 플랫폼은 제품 검색 API에 요청을 보낸 다음, 제품에 대한 더 많은 정보를 검색하기 위해 제품 상세 정보 API에 요청을 보낼 수 있습니다. 이 글에서는 Apache APISIX API Gateway를 위한 사용자 정의 플러그인을 만들어 순차적으로 호출되어야 하는 클라이언트 요청을 처리하는 방법을 살펴보겠습니다.
학습 목표
이 글을 통해 다음을 배우게 됩니다:
- 체이닝 API 요청이란 무엇인가?
- 순차적 API 호출의 예.
- Apache APISIX를 위한 사용자 정의 pipeline-request 플러그인을 구축하는 방법.
- Pipeline-request 플러그인 데모.
체이닝 API 요청이란 무엇이며 왜 필요한가?
체이닝 API 요청(또는 파이프라인 요청, 순차적 API 호출)은 소프트웨어 개발에서 작업을 완료하기 위해 여러 API 호출이 필요한 API 상호작용의 복잡성을 관리하기 위해 사용되는 기술입니다. 이는 배치 요청 처리와 유사하며, 여러 API 요청을 단일 요청으로 그룹화하여 서버에 배치로 보냅니다. 그러나 파이프라인 요청은 서버에 단일 요청을 보내 정의된 순서대로 실행될 API 요청 시퀀스를 트리거하는 것입니다. 시퀀스의 각 API 요청은 요청 및 응답 데이터를 수정할 수 있으며, 하나의 API 요청의 응답은 시퀀스의 다음 API 요청에 입력으로 전달됩니다. 파이프라인 요청은 클라이언트가 특정 순서로 실행되어야 하는 종속적인 API 요청 시퀀스를 실행해야 할 때 유용할 수 있습니다.
파이프라인의 각 단계에서, 다음 단계로 전달하기 전에 응답 데이터를 변환하거나 조작할 수 있습니다. 이는 데이터가 클라이언트에게 반환되기 전에 정규화되거나 변환되거나 민감한 데이터를 필터링해야 하는 상황에서 유용할 수 있습니다. 또한 전체 지연 시간을 줄이는 데 도움이 될 수 있습니다. 예를 들어, 하나의 API 호출이 응답을 기다리는 동안 다른 API 호출을 수행할 수 있어 워크플로우를 완료하는 데 필요한 전체 시간을 줄일 수 있습니다.
Apache APISIX를 위한 사용자 정의 pipeline-request 플러그인
API 게이트웨이는 이 기능을 구현하기에 적합한 장소일 수 있습니다. 왜냐하면 모든 클라이언트 앱 요청을 가로채서 의도된 목적지로 전달할 수 있기 때문입니다. 우리는 Apache APISIX를 사용할 것입니다. 왜냐하면 이는 다양한 내장 플러그인을 갖춘 인기 있는 오픈소스 API 게이트웨이 솔루션입니다. 그러나 현재 블로그 포스트를 개발하는 시점에서 APISIX는 pipeline-request 플러그인에 대한 공식 지원을 제공하지 않았습니다. APISIX의 사용자 정의 플러그인 개발 기능에 대한 지식을 바탕으로, 우리는 동일한 기능을 제공할 수 있는 새로운 플러그인을 소개하기로 결정했습니다. GitHub에는 Lua 프로그래밍 언어로 작성된 소스 코드와 pipeline-request 플러그인에 대한 설명이 있는 저장소가 있습니다.
이 플러그인을 사용하면 단일 클라이언트 요청을 처리하기 위해 순차적으로 호출되어야 하는 업스트림 API 목록을 지정할 수 있습니다. 각 업스트림 API는 요청 및 응답 데이터를 수정할 수 있으며, 하나의 업스트림 API의 응답은 파이프라인의 다음 업스트림 API에 입력으로 전달됩니다. 파이프라인은 Route 구성에서 정의할 수 있으며, 파이프라인이 실행해야 할 API URL의 순서도 정의할 수 있습니다.
이 플러그인의 사용법을 예제를 통해 이해해 보겠습니다. 두 개의 API가 있다고 가정해 보겠습니다. 하나는 GET /credit_cards
요청을 통해 신용카드 정보를 검색하고, 다른 하나는 이전 응답 데이터를 POST /filter
요청의 본문으로 받아 민감한 데이터(예: 신용카드 번호 및 만료일)를 필터링한 후 클라이언트에게 응답을 반환합니다. 신용카드 API 엔드포인트는 권한이 없는 당사자에게 노출되어서는 안 되는 민감한 정보를 반환하기 때문입니다. 아래 다이어그램은 전체 데이터 흐름을 보여줍니다:
- 클라이언트가 API Gateway의 신용카드 API 엔드포인트에 모든 신용카드 정보를 검색하기 위해 요청을 보내면, API Gateway는 신용카드 백엔드 서비스에서 신용카드 데이터를 검색하기 위해 요청을 전달합니다.
- 요청이 성공하고 신용카드 데이터를 반환하면, 파이프라인의 다음 단계로 전달됩니다.
- 보안 서비스에서 필터링된 응답을 받으면, 클라이언트에게 결합된 응답을 반환합니다.
Pipeline-request 플러그인 데모
이 데모를 위해 GitHub에 준비된 또 다른 데모 프로젝트를 활용할 것입니다. 이 프로젝트에서는 이 튜토리얼에서 사용된 모든 curl 명령어 예제를 찾을 수 있으며, APISIX를 실행하고 Docker compose.yml 파일을 통해 추가 구성 없이 사용자 정의 플러그인을 활성화할 수 있습니다.
전제 조건
- Docker는 컨테이너화된 etcd 및 APISIX를 설치하는 데 사용됩니다.
- curl은 APISIX Admin API에 요청을 보내는 데 사용됩니다. Postman과 같은 쉬운 도구를 사용하여 API와 상호작용할 수도 있습니다.
1단계: APISIX 및 etcd 설치 및 실행
프로젝트 루트 폴더에서 docker compose up
을 실행하여 APISIX 및 etcd를 쉽게 설치할 수 있습니다. docker-compose.yml
파일에 ./custom-plugins:/opt/apisix/plugins:ro
볼륨이 지정되어 있음을 알 수 있습니다. 이는 로컬 디렉토리 **./custom-plugins
**를 도커 컨테이너의 /opt/apisix/plugins
경로에 읽기 전용 볼륨으로 마운트합니다. 이는 사용자 정의 플러그인이 런타임에 APISIX에 추가될 수 있도록 합니다(이 설정은 도커로 APISIX를 실행하는 경우에만 적용됩니다).
2단계: pipeline-request 플러그인으로 첫 번째 Route 생성
APISIX가 실행 중이면, APISIX Admin API /routes
엔드포인트에 HTTP PUT 요청을 보내는 cURL 명령어를 사용하여 URI 경로 /my-credit-cards
를 수신하는 첫 번째 경로를 생성합니다.
curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \
--header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
--header 'Content-Type: application/json' \
--data-raw '{
"uri":"/my-credit-cards",
"plugins":{
"pipeline-request":{
"nodes":[
{
"url":"https://random-data-api.com/api/v2/credit_cards"
},
{
"url":"http://127.0.0.1:9080/filter"
}
]
}
}
}'
구성의 중요한 부분은 "plugins" 섹션으로, 이 API 경로에 "pipeline-request" 플러그인을 사용해야 함을 지정합니다. 플러그인 구성에는 파이프라인에서 실행되어야 할 API 요청 시퀀스를 정의하는 "nodes" 배열이 포함됩니다. 여기서 하나 이상의 API를 정의할 수 있습니다. 이 경우, 파이프라인은 두 개의 노드로 구성됩니다: 첫 번째 노드는 https://random-data-api.com/api/v2/credit_cards API에 요청을 보내 신용카드 데이터를 검색하고, 두 번째 노드는 http://127.0.0.1:9080/filter에 있는 로컬 API에 요청을 보내 신용카드 정보에서 민감한 데이터를 필터링합니다. 두 번째 API는 serverless-pre-function APISIX 플러그인을 사용하는 서버리스 함수일 뿐입니다. 이는 첫 번째 API의 응답을 수정하는 백엔드 서비스 역할을 합니다.
3단계: serverless 플러그인으로 두 번째 Route 생성
다음으로, 파이프라인에서 /filter
엔드포인트에 대한 요청을 처리하는 ID 2의 새 경로를 구성합니다. 또한 serverless-pre-function APISIX의 기존 플러그인을 활성화하여 플러그인에 의해 실행되어야 할 Lua 함수를 지정합니다. 이 함수는 이전 응답에서 요청 본문을 검색하고, 신용카드 번호 필드를 대체하며, 나머지 응답은 변경하지 않습니다. 마지막으로, 현재 응답 본문을 수정된 요청 본문으로 설정하고 HTTP 200 응답을 클라이언트에게 반환합니다. 이 스크립트를 수정하여 추가 처리 또는 검증을 수행할 수 있습니다.
curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/2' \
--header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
--header 'Content-Type: application/json' \
--data-raw '
{
"uri": "/filter",
"plugins":{
"serverless-pre-function": {
"phase": "access",
"functions": [
"return function(conf, ctx)
local core = require(\"apisix.core\")
local cjson = require(\"cjson.safe\")
-- Get the request body
local body = core.request.get_body()
-- Decode the JSON body
local decoded_body = cjson.decode(body)
-- Hide the credit card number
decoded_body.credit_card_number = \"****-****-****-****\"
core.response.exit(200, decoded_body);
end"
]
}
}
}'
3단계: 설정 테스트
이제 전체 구성을 테스트할 시간입니다. 아래 curl 명령어를 사용하여 http://127.0.0.1:9080/my-credit-cards
엔드포인트에 HTTP GET 요청을 보냅니다.
curl http://127.0.0.1:9080/my-credit-cards
두 번째 단계에서 pipeline-request
플러그인을 사용하도록 구성된 해당 경로가 있으므로, 이 요청은 https://random-data-api.com/api/v2/credit_cards
엔드포인트에서 신용카드 정보를 검색하고, http://127.0.0.1:9080/filter
엔드포인트를 사용하여 민감한 데이터를 필터링한 후 수정된 응답을 클라이언트에게 반환하는 파이프라인을 트리거합니다. 출력 결과를 확인하세요:
{
"uid":"a66239cd-960b-4e14-8d3c-a8940cedd907",
"credit_card_expiry_date":"2025-05-10",
"credit_card_type":"visa",
"credit_card_number":"****-****-****-****",
"id":2248
}
보시다시피, 요청 본문(실제로는 체인의 첫 번째 API 호출의 응답)에서 신용카드 번호를 별표로 대체했습니다.
요약
지금까지 우리는 Apache APISIX API Gateway를 위한 사용자 정의 pipeline request 플러그인이 특정 순서대로 API 호출 시퀀스를 파이프라인으로 정의할 수 있게 해준다는 것을 배웠습니다. 또한 이 새로운 플러그인을 기존 플러그인과 결합하여 API 엔드포인트에 대한 인증, 보안 및 기타 API Gateway 기능을 활성화할 수도 있습니다.