Apigee를 사용한 API 프록시 설계 및 개발 권장사항

이 페이지는 ApigeeApigee Hybrid에 적용됩니다.

Apigee Edge 문서 보기

이 문서에서는 Apigee로 API 프록시를 개발하기 위한 권장사항을 제공합니다.

이 문서는 설계, 코딩, 정책 사용, 모니터링, 디버깅을 주제로 합니다. Apigee를 사용해 API 프로그램을 성공적으로 구현한 개발자 환경에서 수집한 정보를 바탕으로 합니다. 이 문서는 수정될 수 있으며 수시로 업데이트될 예정입니다.

이 가이드라인 외에도 안티패턴 소개를 참고하면 도움이 될 수 있습니다.

개발 표준

주석 및 문서

  • ProxyEndpointTargetEndpoint 구성에서 인라인 주석을 제공합니다. 주석은 특히 어떤 정책 파일의 이름이 해당 흐름의 기본 기능을 나타내기에 충분히 설명적이지 않은 경우 해당 흐름의 가독성을 향상시키는 데 도움이 됩니다.
  • 유용한 내용을 주석으로 작성합니다. 당연히 알 만한 내용은 피합니다.
  • 일관된 들여쓰기, 간격, 수직 정렬 등을 사용합니다.

프레임워크 스타일 코딩

프레임워크 스타일 코딩에는 로컬 개발 환경 간 재사용이 가능하도록 고유 버전 제어 시스템에 API 프록시 리소스를 저장하는 과정이 포함됩니다. 예를 들어 정책을 재사용하기 위해서는 개발자가 정책을 동기화하고 자신의 고유 프록시 개발 환경에 사용할 수 있도록 정책을 소스 제어에 저장합니다.

  • 가능한 경우 DRY(반복 금지)를 사용 설정하려면 정책 구성 및 스크립트에서 재사용 가능한 특수한 함수를 구현해야 합니다. 예를 들어 요청 메시지에서 쿼리 매개변수를 추출하는 전용 정책의 이름은 ExtractVariables.ExtractRequestParameters가,
  • API 프록시에서 사용하지 않는 정책 및 리소스(자바스크립트, 자바, XSLT), 특히 가져오기 및 배포 절차를 지연시킬 수 있는 대규모 리소스를 삭제합니다.

이름 지정 규칙

  • 정책 name 속성과 XML 정책 파일 이름은 동일해야 합니다.
  • 스크립트 및 ServiceCallout 정책 정책 name 속성과 리소스 파일 이름이 동일해야 합니다.
  • DisplayName은 이전에 해당 API 프록시로 작업한 적이 없는 사용자에게 정책의 기능을 정확하게 설명해야 합니다.
  • 기능별 이름 정책. Apigee는 정책의 일관된 이름 지정 규칙을 설정하는 것을 권장합니다. 예를 들어 짧은 프리픽스 다음에 대시로 구분된 일련의 단어를 사용합니다. 예를 들어 AssignMessage 정책의 경우 AM-xxx를 사용합니다. apigeelint 도구도 참조하세요.
  • 리소스 파일에 적절한 확장자를 사용합니다(예: 자바스크립트에 .js, Python에 .py, 자바 JAR 파일에 .jar 사용).
  • 변수 이름은 일관적이어야 합니다. camelCase 또는 under_score와 같은 스타일을 선택한 경우 이를 API 프록시 전반에 걸쳐 사용해야 합니다.
  • 가능한 경우 Consumer.usernameConsumer.password와 같이 해당 목적에 따라 변수 프리픽스를 사용하여 변수를 정리합니다.

API 프록시 개발

초기 설계 고려사항

  • RESTful API 설계에 대한 안내를 보려면 eBook 웹 API 설계: 잃어버린 고리를 다운로드합니다.
  • 가능한 모든 경우 Apigee 정책 및 기능을 활용해서 API 프록시를 빌드합니다. 자바스크립트, 자바, Python 리소스에서 모든 프록시 논리를 코딩하지 않도록 합니다.
  • 체계적인 방식으로 흐름을 구성합니다. 각각 조건을 가지는 다중 흐름은 PreFlow 및 Postflow에 대한 여러 조건부 연결보다 선호됩니다.
  • '안전 조치'로 ProxyEndpoint BasePath가 /인 기본 API 프록시를 만듭니다. 이를 통해 기본 API 요청을 개발자 사이트로 리디렉션하거나, 맞춤 응답을 반환하는 데 사용하거나, 기본 messaging.adaptors.http.flow.ApplicationNotFound를 반환하는 것보다 더 유용한 작업을 수행하는 데 사용할 수 있습니다.
  • TargetServer 리소스를 사용하여 TargetEndpoint 구성을 구체적인 URL에서 분리하여 여러 환경에서의 승격을 지원합니다.
    백엔드 서버 간 부하 분산을 참조하세요.
  • RouteRule이 여러 개이면 하나를 'default'로 만듭니다. 즉, 조건이 없는 RouteRule로 만듭니다. 기본 RouteRule이 조건부 경로 목록에서 마지막으로 정의되었는지 확인합니다. RouteRule은 ProxyEndpoint에서 위에서 아래의 순서로 평가됩니다. API 프록시 구성 참조를 확인하세요.
  • API 프록시 번들 크기: API 프록시 번들은 15MB보다 클 수 없습니다.
  • API 버전 관리: Apigee의 API 버전 관리에 대한 생각과 권장사항은 웹 API 설계: 잃어버린 고리 eBook의 버전 관리를 참조하세요.

CORS 사용 설정

API를 게시하기 전에 ProxyEndpoint의 요청 PreFlow에 CORS 정책을 추가하여 클라이언트 측 교차 출처 요청을 지원해야 합니다.

CORS(교차 출처 리소스 공유)는 웹페이지에서 실행되는 자바스크립트 XMLHttpRequest(XHR) 호출이 출처가 다른 도메인의 리소스와 상호작용할 수 있도록 허용하는 표준 메커니즘입니다. CORS는 모든 브라우저에서 적용되는 동일 출처 정책에 일반적으로 구현되는 솔루션입니다. 예를 들어 브라우저에서 실행되는 자바스크립트 코드에서 Twitter API로 XHR 호출을 수행하면 호출이 실패합니다. 이는 브라우저에 페이지를 제공하는 도메인이 Twitter API를 제공하는 도메인과 동일하지 않기 때문입니다. CORS는 이 문제를 해결하기 위해 서버가 교차 출처 리소스 공유를 제공하려는 경우 선택을 하도록 허용하는 솔루션을 제공합니다.

API를 게시하기 전 API 프록시에서 CORS를 사용 설정하는 방법에 대한 자세한 내용은 API 프록시에 CORS 지원 추가를 참조하세요.

메시지 페이로드 크기

Apigee에서 메모리 문제를 방지하기 위해 메시지 페이로드 크기가 10MB로 제한됩니다. 이러한 크기를 초과하면 protocol.http.TooBigBody 오류가 발생합니다.

이 문제는 Apigee 프록시로 대규모 페이로드를 요청/반환하는 중에 오류에도 설명되어 있습니다.

다음은 Apigee에서 큰 메시지 크기를 처리할 때 권장되는 전략입니다.

  • 요청 및 응답 스트리밍 스트리밍하면 정책에서 더 이상 메시지 콘텐츠에 액세스할 수 없습니다. 요청 및 응답 스트리밍을 참조하세요.

오류 처리

  • 모든 오류 처리를 다루기 위해 FailedRules를 활용합니다. (RaiseFault 정책은 메시지 흐름을 중지하고 FaultRules 흐름으로 메시지를 전송하는 데 사용됩니다.)
  • FaultRule 흐름에서 RaiseFault 정책이 아닌 AssignMessage 정책을 사용하여 오류 응답을 빌드합니다. 발생하는 오류 유형에 따라 AssignMessage 정책을 조건부로 실행합니다.
  • 항상 기본 '포괄' 오류 핸들러를 포함하여 시스템 생성 오류를 고객 정의 오류 응답 형식에 매핑할 수 있도록 합니다.
  • 가능한 경우 항상 회사나 프로젝트에서 사용 가능한 표준 형식과 동일한 오류 응답을 만드세요.
  • 오류 조건에 대한 해결 방법을 제안하는 의미 있고 사람이 이해할 수 있는 오류 메시지를 사용하세요.

오류 처리를 참고하세요.

지속성

키/값 맵

  • 제한된 데이터 세트에 대해서만 키/값 맵을 사용합니다. 키/값 맵은 장기 데이터 저장소로 디자인되지 않았습니다.
  • 이 정보는 Cassandra 데이터베이스에 저장되므로 키/값 맵을 사용할 때 성능을 고려하세요.

KeyValueMapOperations 정책을 참조하세요.

응답 캐싱

  • 응답이 실패하거나 요청이 GET이 아닌 경우 응답 캐시를 채우지 마세요. 만들기, 업데이트, 삭제는 캐시되지 않아야 합니다. <SkipCachePopulation>response.status.code != 200 or request.verb != "GET"</SkipCachePopulation>
  • 일관된 단일 콘텐츠 유형(예: XML 또는 JSON)으로 캐시를 채웁니다. responseCache 항목을 가져온 후 JSONtoXML 또는 XMLToJSON을 사용해 필요한 콘텐츠 유형으로 변환합니다. 그러면 데이터가 두세 배 이상으로 저장되지 않습니다.
  • 캐시 키가 캐시 요구사항을 충족하기에 충분한지 확인합니다. 대부분의 경우 request.querystring을 고유 식별자로 사용할 수 있습니다.
  • 명시적으로 필요한 경우가 아니라면 캐시 키에 API 키(client_id)를 포함하지 마세요. 대부분의 경우 키로만 보호되는 API는 특정 요청에 대해 모든 클라이언트에 동일한 데이터를 반환합니다. API 키를 기준으로 많은 항목에 대해 동일한 값을 저장하는 것은 효율적이지 않습니다.
  • 더티 읽기를 방지하기 위해 적절한 캐시 만료 간격을 설정합니다.
  • 가능하다면 캐시를 채우는 응답 캐시 정책이 ProxyEndpoint 응답 PostFlow에서 최대한 늦게 실행되도록 합니다. 즉, 자바스크립트 기반 미디에이션과 JSON 및 XML 간 변환을 포함한 변환 및 미디에이션 단계 후에 정책이 실행되어야 합니다. 미디에이션된 데이터를 캐시하면 캐시된 데이터를 검색할 때마다 미디에이션 단계를 실행하는 데에 따른 성능 비용이 발생하지 않습니다.

    미디에이션에서 요청마다 다른 응답을 생성하는 경우 미디에이션되지 않은 데이터를 대신 캐시해야 할 수도 있습니다.

  • 캐시 항목을 조회하는 응답 캐시 정책은 ProxyEndpoint 요청 PreFlow에서 실행되어야 합니다. 캐시 항목을 반환하기 전에 캐시 키 생성 이외의 로직을 과도하게 구현하지 마세요. 너무 많은 로직을 구현하면 캐시의 이점이 최소화됩니다.
  • 일반적으로 항상 응답 캐시 조회를 클라이언트 요청과 가능한 한 가깝게 유지해야 합니다. 반대로 응답 캐시 채우기는 클라이언트 응답과 가능한 한 가깝게 유지해야 합니다.
  • 프록시에서 다양한 여러 응답 캐시 정책을 사용하는 경우 다음 가이드라인에 따라 각각 별개의 동작을 보장하세요.
    • 상호 배타적인 조건에 따라 각 정책을 실행합니다. 이렇게 하면 여러 응답 캐시 정책 중 하나만 실행되도록 보장할 수 있습니다.
    • 각 응답 캐시 정책에 대해 서로 다른 캐시 리소스를 정의합니다. 정책의 <CacheResource> 요소에 캐시 리소스를 지정합니다.

ResponseCache 정책을 참조하세요.

정책 및 맞춤 코드

정책 또는 맞춤 코드?

  • 가능한 경우 기본 정책을 우선으로 사용하세요. Apigee 정책은 강화 및 최적화되어 지원됩니다. 예를 들어, 페이로드를 생성하기 위해 자바스크립트(가능한 경우) 대신 AssignMessage 정책ExtractVariables 정책 정책을 사용하여 페이로드(XPath, JSONPath 등)에서 정보를 추출합니다.
  • Python 및 자바보다 자바스크립트를 사용하는 것이 좋습니다. 하지만 성능이 기본 요구사항인 경우에는 자바스크립트보다 자바를 사용해야 합니다.

자바스크립트

  • Apigee 정책보다 직관적인 경우(예: 여러 다양한 URI 조합에 target.url을 설정하는 경우) 자바스크립트를 사용하세요.
  • JSON 객체 및 Base64 인코딩/디코딩을 통한 반복과 같은 복잡한 페이로드 파싱입니다.
  • 자바스크립트 정책에는 시간 제한이 있으므로 무한 루프가 차단됩니다.
  • 항상 자바스크립트 단계를 사용하고 jsc 리소스 폴더에 파일을 저장합니다. 자바스크립트 정책 유형에서는 배포 시에 코드를 사전 컴파일합니다.

자바

  • 성능이 최우선순위이거나 자바스크립트에서 로직을 구현할 수 없는 경우 자바를 사용합니다.
  • 소스 코드 추적에 자바 소스 파일을 포함합니다.

API 프록시에서 자바 사용에 대한 자세한 내용은 JavaCallout 정책을 참조하세요.

Python

  • 반드시 필요한 경우가 아니라면 Python을 사용하지 마세요. Python 스크립트는 런타임에 해석되기 때문에 간단한 실행의 경우에도 성능 병목 현상을 일으킬 수 있습니다.

스크립트 콜아웃(자바, 자바스크립트, Python)

  • 전역 try/catch 또는 이와 동등한 것을 사용합니다.
  • 의미 있는 예외를 발생시키고 오류 응답에 사용할 수 있도록 적절히 포착합니다.
  • 예외를 조기에 발생시키고 포착합니다. 모든 예외를 처리하기 위해 전역 try/catch를 사용하지 마세요.
  • 필요한 경우 널 및 정의되지 않은 검사를 수행하세요. 이를 수행해야 할 경우에 대한 예시는 선택적인 흐름 변수를 검색할 때입니다.
  • 스크립트 콜아웃 내부에서 HTTP/S 요청을 수행하지 마세요. 정책이 연결을 매끄럽게 처리하므로 대신 ServiceCallout 정책을 사용합니다.

자바스크립트

  • API 플랫폼의 자바스크립트는 E4X를 통해 XML을 지원합니다.

자바스크립트 객체 모델을 참조하세요.

자바

  • 메시지 페이로드에 액세스할 때 context.getMessage()context.getResponseMessage 또는 context.getRequestMessage를 비교하며 사용해 보세요. 이렇게 하면 코드가 요청 및 응답 흐름 모두에서 페이로드를 검색할 수 있습니다.
  • 라이브러리를 Apigee 조직 또는 환경으로 가져오되 JAR 파일에는 포함시키지 않습니다. 그러면 번들 크기가 줄어들고 다른 JAR 파일이 동일한 라이브러리 저장소에 액세스할 수 있습니다.
  • API 프록시 리소스 폴더 안에 포함하는 대신 Apigee 리소스 API를 사용하여 JAR 파일을 가져옵니다. 그러면 배포 시간이 줄어들고 동일한 JAR 파일을 여러 API 프록시가 참조할 수 있습니다. 또 다른 이점은 클래스 로더 격리입니다.
  • 리소스 처리에 자바를 사용하지 않습니다(예: 스레드 풀 생성 및 관리).

Python

  • 의미 있는 예외를 발생시키고 Apigee 오류 응답에 사용할 수 있도록 적절히 포착합니다.

PythonScript 정책을 참조하세요.

ServiceCallouts

  • 하나의 API 프록시에서 서비스 콜아웃을 사용하여 다른 API 프록시를 호출하는 프록시 체인 사용에 대한 유효한 사용 사례가 많이 있습니다. 프록시 체인을 사용하는 경우 무한 루프 반복 콜아웃이 동일한 API 프록시로 다시 발생하지 않도록 합니다.

    동일한 조직 및 환경에 있는 프록시 간에 연결하는 경우 불필요한 네트워크 오버헤드를 방지하는 로컬 연결 구현에 대한 자세한 내용은 API 프록시 체이닝을 참조하세요.

  • AssignMessage 정책을 사용하여 ServiceCallout 요청 메시지를 빌드하고 메시지 변수에 요청 객체를 채웁니다. (여기에는 요청 페이로드, 경로, 메서드 설정이 포함됩니다.)
  • 정책 내에 구성된 URL에는 프로토콜 사양이 필요합니다. 즉, URL의 프로토콜 부분(예: https://)은 변수로 지정할 수 없습니다. 또한 URL의 도메인 부분과 그 외 부분에 별도의 변수를 사용해야 합니다. 예를 들면 https://example.com입니다.
  • ServiceCallout 의 응답 객체를 별도의 메시지 변수에 저장합니다. 그런 다음 메시지 변수를 파싱하고 원본 메시지 페이로드를 다른 정책에서 사용하도록 그대로 유지할 수 있습니다.

ServiceCallout 정책을 참조하세요.

항목 액세스

AccessEntity 정책

  • 성능을 높이려면 앱 이름 대신 uuid로 앱을 찾으세요.

AccessEntity 정책을 참조하세요.

로깅

  • 여러 번들과 동일 번들 내에서 일반적인 시스템로그 정책을 사용합니다. 그러면 일관된 로깅 형식을 유지할 수 있습니다.

MessageLogging 정책을 참조하세요.

모니터링

클라우드 고객은 Apigee의 개별 구성요소(라우터, 메시지 프로세서 등)를 확인할 필요는 없습니다. Apigee의 글로벌 운영팀은 고객의 상태 확인 요청에 따라 API 상태 확인과 함께 모든 구성요소를 철저히 모니터링합니다.

Apigee 애널리틱스

애널리틱스에서는 오류율이 측정되어 중요하지 않은 API의 모니터링을 제공할 수 있습니다.

애널리틱스 대시보드를 참조하세요.

디버깅

Apigee UI의 trace 도구는 API 개발 또는 프로덕션 작업 중에 런타임 API 문제를 디버깅하는 데 유용합니다.

디버그 도구 사용을 참조하세요.

보안

API 프록시의 커스텀 로직

API 프록시를 빌드할 때는 요청 및 응답을 처리하는 특정 로직을 포함해야 하는 경우가 많습니다. 사전 정의된 단계/작업/정책을 통해 토큰 확인, 할당량 적용, 캐시된 객체로 응답과 같은 여러 가지 요구사항을 충족할 수 있지만 프로그래밍 방식으로 해결해야 할 수도 있습니다. 예를 들어 요청에 있는 키를 기반으로 라우팅 테이블에서 위치(엔드포인트)를 조회하여 대상 엔드포인트 또는 커스텀/독점 인증 방법 등을 동적으로 적용해야 합니다.

Apigee는 개발자에게 이러한 커스텀 로직을 처리하는 여러 옵션을 제공합니다. 이 문서에서는 이러한 옵션을 살펴보고 언제 무엇을 사용해야 하는지에 대해 설명합니다.

정책 정책 사용 사례
자바스크립트 및 PythonScript

사용 시점:

  • 자바스크립트 및 PythonScript 정책은 기능이 동일합니다. 한 언어에 익숙한 개발자는 일반적으로 다른 언어를 선택해서 사용할 수도 있습니다.
  • 자바스크립트 및 PythonScript 정책은 너무 복잡하지 않고 타사 라이브러리를 사용할 필요가 없는 인라인 처리 로직에 가장 적합합니다.
  • 이러한 정책은 JavaCallout 정책보다 성능이 떨어집니다.

사용이 적합하지 않은 경우:

  • Apigee의 API 게이트웨이는 애플리케이션 서버가 아니며 node.js 같은 전체 자바스크립트 런타임을 제공하지 않습니다. 콜아웃 처리 시간이 항상 1초를 넘는 경우 로직이 게이트웨이에 속해서는 안 되며 기본 서비스의 일부여야 합니다.

권장사항: 자바스크립트의 성능이 더 우수하므로 Apigee는 PythonScript보다 자바스크립트를 권장합니다.

JavaCallout

사용 시점:

  • 인라인 로직을 처리하는 성능이 중요합니다.
  • 기존 자바 라이브러리가 로직의 상당 부분을 제공합니다.

사용이 적합하지 않은 경우:

  • Apigee의 API 게이트웨이는 애플리케이션 서버가 아니며 Spring, JEE 등의 프레임워크를 로드하지 않습니다. 콜아웃 처리 시간이 일반적으로 1초를 넘는 경우 로직을 기능(비즈니스 로직)으로 간주할 수 있습니다. 별도의 서비스로 외부화하는 방법을 고려하세요.
  • Apigee API 게이트웨이가 악용되지 않도록 보호하기 위해 실행 가능한 코드 유형에 대한 제한이 있습니다. 예를 들어 특정 암호화 라이브러리에 액세스하거나 파일 시스템에 액세스하려는 자바 코드는 실행이 차단됩니다.
  • 자바 애플리케이션, 특히 타사 라이브러리에 의존하는 애플리케이션에는 대규모 JAR 파일이 많이 사용될 수 있습니다. 이로 인해 게이트웨이 부팅 시간이 느려질 수 있습니다.
ExternalCallout

사용 시점:

  • 커스텀 로직을 외부화하고 커스텀 로직이 메시지 컨텍스트에 액세스하거나 필요한 경우 수정하도록 허용하는 데 이상적입니다.
  • 외부 콜아웃은 gRPC를 구현하며 ServiceCallout보다 성능이 우수할 수 있습니다.
  • Google Cloud에서 Apigee 또는 Apigee Hybrid를 사용하는 경우 Cloud Functions 또는 Cloud Run을 사용하여 해당 로직을 호스팅하는 것이 좋습니다.
  • Apigee Edge의 호스팅된 대상 기능을 효과적으로 대체합니다.

사용이 적합하지 않은 경우:

  • 인라인으로 빠르게 실행할 수 있는 간단한 로직
ServiceCallout

사용 시점:

  • 복잡한 로직은 게이트웨이 외부에서 구현하는 것이 가장 좋습니다. 이 로직은 고유한 수명 주기(출시 및 버전 관리)를 가지며, 게이트웨이의 작동에 영향을 주지 않습니다.
  • REST/SOAP/GraphQL 엔드포인트가 이미 있거나 쉽게 구현될 수 있음
  • Google Cloud에서 Apigee 또는 Apigee Hybrid를 사용하는 경우 Cloud Functions 또는 Cloud Run을 사용하여 해당 로직을 호스팅하는 것이 좋습니다.
  • Apigee Edge의 호스팅된 대상 기능을 효과적으로 대체합니다.

사용이 적합하지 않은 경우:

  • 인라인으로 빠르게 실행할 수 있는 간단한 로직
  • API 프록시가 변수 등의 컨텍스트를 전송하거나 외부 구현에서 컨텍스트를 수신해야 합니다.

요약

  1. 로직이 단순하거나 사소한 경우 가급적 자바스크립트, 아니면 PythonScript를 사용합니다.
  2. 인라인 로직에 자바스크립트 또는 PythonScript보다 우수한 성능이 필요한 경우 JavaCallout을 사용합니다.
  3. 로직을 외부화해야 하는 경우 ExternalCallout을 사용합니다.
  4. 이미 외부 구현이 있거나 개발자가 REST에 익숙하다면 ServiceCallout을 사용합니다.

다음은 프로세스를 보여주는 흐름도입니다.