블로그 | NGINX

NGINX Plus 및 NGINX JavaScript 모듈을 사용한 API 요청 일괄 처리

NGINX-F5-수평-검정-유형-RGB의 일부
릭 넬슨 썸네일
릭 넬슨
2018년 5월 24일 게시

NGINX Plus R15 와 함께 출시된 NGINX JavaScript 모듈 버전은 이제 하위 요청을 발행할 수 있습니다. 즉, JavaScript 코드에서 요청을 시작할 수 있습니다. 이를 통해 완전히 새로운 사용 사례를 다룰 수 있습니다.

이러한 사용 사례 중 하나는 API 요청을 일괄 처리하여 클라이언트의 단일 API 요청을 일련의 백엔드 서버에 대한 여러 API 요청으로 전환하고, 응답을 클라이언트에 대한 단일 응답으로 집계하는 것입니다. 이 블로그에서는 전자상거래 사이트를 예로 들어보겠습니다. 클라이언트가 특정 제품에 대한 정보를 요청하면 카탈로그, 재고, 고객 리뷰라는 세 가지 백엔드 서비스에 하위 요청이 이루어집니다.

이 게시물은 NGINX Plus R15 발표 에서 소개된 하위 요청 예제를 기반으로 하며, 하위 요청을 사용하여 동일한 요청을 두 개의 백엔드 서버로 보내고 첫 번째 응답만 클라이언트에 반환하는 방법을 보여줍니다.

[ 편집자 - 이 게시물은 NGINX JavaScript 모듈의 사용 사례를 살펴보는 여러 게시물 중 하나입니다. 전체 목록은 NGINX JavaScript 모듈의 사용 사례를 참조하세요.

게시물이 업데이트되어 사용됩니다. js_import 지시문은 다음을 대체합니다. js_포함 지시문에 NGINX 플러스 R23 그리고 나중에. 자세한 내용은 NGINX JavaScript 모듈 의 참조 문서를 참조하세요. 예제 구성 섹션에서는 NGINX 구성 및 JavaScript 파일에 대한 올바른 구문을 보여줍니다.

소개

이 게시물의 목적은 간단하고 이해하기 쉬운 API 요청 일괄 처리의 실제 사례를 제공하는 것입니다. 이 예제는 다음 요구 사항을 모두 충족합니다.

  • 모든 요청에는 HTTP GET 방식이 사용됩니다.
  • 모든 응답은 JSON 형식입니다.
  • 두 가지 스타일의 API 요청이 지원됩니다.

    • API 프로그램에 대한 인수는 URI의 마지막 요소입니다. 이것을 final‑element 요청 스타일 이라고 합니다. 예를 들어, /batch-api/product/14286 에 대한 클라이언트 요청은 /myapi/catalog/14286 , /myapi/inventory/14286 , /myapi/review/14286 에 대한 요청을 생성합니다.
    • 인수는 URI의 쿼리 문자열에서 식별됩니다. 이를 쿼리 문자열 요청 스타일이라고 합니다. 이 예에서 /batch-api2/product?item=14286 에 대한 요청은 /myapi/catalog.php?item=14286 , /myapi/inventory.php?item=14286 , /myapi/review.php?item=14286 에 대한 요청을 생성합니다.

    두 스타일 모두 쿼리 문자열에 추가 인수가 있을 수 있습니다.

  • 클라이언트 요청에 의해 트리거되는 하위 요청 세트는 동적으로 구성 가능하므로 NGINX Plus 구성을 수동으로 편집하고 다시 로드하지 않고도 변경할 수 있습니다.
  • 백엔드 서버에 대한 API 요청은 서로 독립적입니다.

솔루션 개요

NGINX JavaScript의 새로운 하위 요청 기능을 사용하는 것 외에도 이 솔루션은 NGINX Plus의 키‑값 저장 기능을 활용하여 NGINX Plus API를 사용하여 구성을 동적으로 변경할 수 있습니다.

다음 그래픽은 지원되는 두 가지 요청 스타일을 보여줍니다.

최종 요소 요청 스타일:

클라이언트가 API에 최종 요소 스타일 요청을 합니다.

쿼리 문자열 요청 스타일:

클라이언트는 API에 쿼리 문자열 스타일 요청을 합니다.

두 가지 예에서 모두, 클라이언트는 카탈로그, 재고, 리뷰 서비스를 통해 제품에 대한 정보를 얻어야 합니다. NGINX Plus에 하나의 요청을 보내는데, 이때 항목 번호를 URI의 일부로 전달하거나 쿼리 문자열에 포함합니다. 그런 다음 요청은 세 서비스로 전송되고 응답은 클라이언트에 대한 단일 응답으로 집계됩니다.

이 작업을 NGINX Plus에서 수행하려면 JavaScript 프로그램NGINX Plus 구성이라는 두 가지 구성 요소가 필요합니다.

자바스크립트 프로그램

각 클라이언트 요청에 대해 JavaScript 함수 batchAPI()가 호출됩니다. 키-값 저장소에서 API URI의 쉼표로 구분된 목록을 가져와 이를 반복하면서 각각에 대한 하위 요청을 만들고 각 응답을 처리하기 위한 콜백 함수 done()을 지정합니다. 최종 요소 스타일 요청의 경우 NGINX 변수 $uri_suffix 에 저장된 URI의 마지막 요소가 원래 클라이언트 URI의 다른 쿼리 문자열 인수와 함께 각 하위 요청의 쿼리 문자열로 전달됩니다. 쿼리 문자열 스타일 요청의 경우 클라이언트 요청의 쿼리 문자열이 각 하위 요청의 쿼리 문자열로 전달됩니다.

호출은 키-값 저장소에 나열된 순서대로 이루어지지만 비동기적이므로 응답은 어떤 순서로든 돌아올 수 있습니다. 응답은 수신된 순서대로 클라이언트에 대한 하나의 응답으로 집계됩니다. JavaScript 프로그램의 최소 버전은 다음과 같습니다.

더욱 광범위한 오류 처리, 로깅 및 주석 기능을 갖춘 JavaScript 프로그램 버전은 GitHub Gist repo에서 batch-api.js 로 제공됩니다.

최소 NGINX Plus 구성

다음 NGINX Plus 구성은 업스트림 서버 그룹을 사용하여 위에서 설명한 두 가지 요청 스타일을 구현합니다. 간단하게 하기 위해 이 구성에서는 업스트림 서버가 /myapi/ service / item# (최종 요소 스타일) 형식의 호출 /myapi/service.php/?item=item# (쿼리 문자열 스타일)으로 변환할 수 있다고 가정합니다. 이는 샘플 카탈로그, 인벤토리 및 리뷰 서비스에 사용되는 언어인 PHP의 "네이티브" URI 형식입니다.

URI를 직접 변환하는 보다 광범위한 NGINX Plus 구성에 대한 자세한 내용은 아래의 URI를 변환하기 위한 NGINX 구성 확장을 참조하세요.

구성 파일을 섹션별로 살펴보고 각 부분의 기능을 설명하겠습니다.

  • JavaScript 파일 가져오기 :

  • URI의 마지막 요소가 API 프로그램에 대한 인수를 식별하는 API 요청 목록을 보관할 키-값 저장소를 정의합니다. 키는 $uri_prefix 변수를 사용하여 마지막 / 이전의 URI 부분을 캡처합니다.

    NGINX Plus R16 이상에서는 두 가지 추가 키-값 기능을 활용할 수 있습니다.

    • keyval_zone 지시문에 timeout 매개변수를 추가하여 키‑값 저장소의 항목에 대한 만료 시간을 설정합니다. 예를 들어, 일괄 처리된 URI가 매일 만료되도록 하려면 timeout=1d를 추가합니다.
    • keyval_zone 지시문에 sync 매개변수를 추가하여 NGINX Plus 인스턴스 클러스터에서 키‑값 저장소를 동기화합니다. 이 경우에는 시간 초과 매개변수도 포함해야 합니다.

    키-값 저장소에 대한 동기화를 설정하는 방법에 대한 자세한 내용은 NGINX Plus 관리자 가이드를 참조하세요.

  • 인수가 쿼리 문자열에서 식별되는 API에 대해 또 다른 키‑값 저장소를 정의합니다. 여기서 키( $uri )는 쿼리 문자열을 포함하지 않는 전체 URI를 캡처합니다.

  • 인수가 URI의 마지막 요소인 요청을 수락하는 API의 경우 URI를 두 부분으로 분할하기 위해 두 개의 맵을 정의합니다. $uri_prefix 변수는 마지막 / 이전의 URI 요소를 캡처하고 $uri_suffix는 마지막 요소를 캡처합니다.

  • API 서버의 업스트림 그룹을 정의합니다(여기서는 NGINX Plus와 함께 로컬호스트에서 실행됨):

  • 클라이언트 요청과 하위 요청을 처리하는 가상 서버를 정의합니다.

  • $batch_api_arg_in_uri 변수를 on 으로 설정하여 batchAPI 함수에 표시되는 최종 요소 스타일을 사용하는 클라이언트 요청을 처리할 위치를 정의합니다.

  • $batch_api_arg_in_uri 변수를 off 로 설정하여 batchAPI 함수에 표시되는 쿼리 문자열 스타일을 사용하는 클라이언트 요청을 처리할 위치를 정의합니다.

  • 하위 요청을 처리하는 위치를 정의합니다.

  • NGINX Plus API를 활성화하여 키-값 저장소에 데이터를 보관할 수 있습니다.

전체 구성은 다음과 같습니다.

일괄 처리된 API 요청 구성

NGINX Plus 키‑값 저장 기능을 사용하여 인바운드 클라이언트 요청을 실행할 API 요청 세트에 매핑합니다. 이전 섹션 의 구성은 두 가지 요청 스타일에 대해 별도의 키-값 저장소를 정의합니다.

  • 최종 요소 스타일의 키-값 저장소는 batch_api 라는 이름이 지정되고 키는 $uri_prefix 변수입니다. 이 변수는 요청 URI의 마지막 / 앞에 있는 요소를 캡처합니다.
  • 쿼리 문자열 스타일의 키-값 저장소는 batch_api2 라는 이름이 지정되고 키는 $uri 변수입니다. 이 변수는 쿼리 문자열을 제외한 전체 요청 URI를 캡처합니다.

두 키-값 저장소에서 각 키와 연관된 값은 $batch_api 또는 $batch_api2 변수에서 런타임에 사용 가능한 URI의 쉼표로 구분된 목록입니다.

최종 요소 스타일 요청의 경우 /batch-api/product 에 대한 클라이언트 요청을 세 가지 서비스 /myapi/catalog , /myapi/inventory/myapi/review 에 대한 요청으로 매핑하고, /batch-api/product/14286 에 대한 요청이 /myapi/catalog/14286 , /myapi/product/14286/myapi/review/14286 에 대한 요청으로 이어지도록 하려고 합니다.

이러한 매핑을 batch_api 키‑값 저장소에 추가하려면 로컬 머신에서 실행되는 NGINX Plus 인스턴스에 다음 요청을 보냅니다.

$ curl -iX POST -d '{"/배치-api/제품":"/myapi/카탈로그,/myapi/인벤토리,/myapi/리뷰"}' http://localhost/api/3/http/keyvals/배치_api

쿼리 문자열 스타일 요청의 경우, /batch-api2/product 에 대한 클라이언트 요청을 세 가지 서비스 /myapi/catalog.php , /myapi/inventory.php , /myapi/review.php 에 대한 요청으로 매핑하고 싶습니다. 즉 , /batch-api2/product?item=14286 에 대한 요청이 /myapi/catalog?item=14286 , /myapi/product?item=14286 , /myapi/review?item=14286 에 대한 요청으로 이어지도록 합니다.

이러한 매핑을 batch_api2 키‑값 저장소에 추가하려면 다음 요청을 보냅니다.

$ curl -iX POST -d '{"/batch-api2/product":"/myapi/catalog.php,/myapi/inventory.php,/myapi/review.php"}' http://localhost/api/3/http/keyvals/batch_api2

예제 실행

동일한 PHP 페이지가 두 가지 요청 스타일로 이루어진 요청을 모두 처리합니다. 단순화를 위해 백엔드 서버가 최종 요소 스타일 URI( /myapi/ service / item# )를 쿼리 문자열 스타일 URI( /myapi/ service .php?item= item# )로 변환할 수 있다고 가정합니다. PHP 프로그램의 "네이티브" URI 형식이 쿼리 문자열 스타일 URI이므로 이를 번역할 필요는 없습니다.

모든 서비스는 서비스 이름과 항목 인수가 포함된 JSON 형식의 응답을 반환합니다. 예를 들어, /myapi/catalog.php?item=14286 에 대한 요청은 catalog.php 에서 다음과 같은 응답을 생성합니다.

{"service":"카탈로그","item":"14286"}

이러한 예제에서 사용된 PHP 프로그램은 응답에 서비스 이름을 포함하지만 모든 서비스에 해당되는 것은 아닙니다. JavaScript 프로그램은 집계된 응답에 URI를 포함시켜 해당 응답을 생성한 서비스에 맞는 응답을 찾을 수 있도록 합니다.

예를 들어, /batch-api/product/14286 에 대한 요청에 대한 집계된 응답은 다음과 같습니다(단, 세 가지 구성 요소 응답의 순서는 다를 수 있음).

[["/myapi/review/14286",{"service":"리뷰","item":"14286"}],["/myapi/inventory/14286",{"service":"인벤토리","item":"14286"}],["/myapi/catalog/14286",{"service":"카탈로그","item":"14286"}]]

URI를 변환하기 위한 NGINX Plus 구성 확장

위에서 설명한 대로, 최소 NGINX Plus 구성은 API 서버가 /myapi/ service / item# 형식의 URI를 /myapi/service.php/?item=item# 형식 으로 변환할 수 있다고 가정합니다. 다음과 같이 변경하면 NGINX Plus 구성에서 번역을 구현할 수도 있습니다.

  • 하위 요청을 수신하기 위해 새로운 업스트림 그룹을 추가합니다.

  • 서비스 업스트림 그룹에서 수신한 요청을 수신하기 위해 새로운 가상 서버를 추가합니다. 쿼리 문자열 스타일의 요청을 받으면 URI에 이미 .php 확장자가 있으므로 해당 요청은 단순히 api_servers 업스트림 그룹으로 프록시됩니다. 최종 요소 스타일 요청이 수신되면 URI가 다시 작성되어 URI의 마지막 요소가 제거되고 쿼리 문자열 인수로 변환됩니다.

  • /myapi 위치를 새 업스트림 그룹으로 프록시하도록 변경합니다.

전체 구성은 다음과 같습니다.

추가 구성 요소

샘플 JavaScript 프로그램과 NGINX Plus 구성은 다른 스타일의 API에 맞게 조정할 수 있지만 이 블로그 게시물을 만드는 데 사용된 모든 구성 요소를 사용하여 테스트하려면 GitHub의 Gist 리포지토리에서 PHP 페이지를 제공하기 위한 NGINX Unit 구성을 포함하여 사용할 수 있습니다.

배치-api.js
카탈로그.php
인벤토리.php
리뷰.php
단위.config

결론

이러한 예제에서는 API 요청을 일괄 처리하고 클라이언트에 집계된 응답을 제공하는 방법을 보여줍니다. NGINX Plus 키-값 저장소를 사용하면 NGINX Plus API를 사용하여 API 요청을 동적으로 구성할 수 있습니다. API 시스템은 정확한 작업이 매우 다양하므로 특정 API의 요구 사항에 맞게 이 예제를 많이 개선할 수 있습니다.

NGINX 오픈 소스를 사용하여 NGINX JavaScript 하위 요청 테스트를 시작할 수 있지만 API 배칭 예제를 시도하거나 키‑값 저장소 및 NGINX Plus API 와 같은 NGINX Plus 기능을 활용하는 다른 사용 사례를 테스트하려면 30일 무료 평가판을 요청 하여 실험을 시작하세요.


"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."