데코레이터

Python용 Cloud Endpoints Frameworks 데코레이터는 API 구성, 메서드, 매개변수, Endpoints의 속성과 동작을 정의하는 기타 중요한 세부정보를 설명합니다.

이 페이지에서는 사용 가능한 데코레이터를 자세히 설명합니다. 데코레이터를 사용하여 API를 만드는 방법에 대한 자세한 내용은 다음을 참조하세요.

API 정의하기(@endpoints.api)

API를 정의하기 위해 @endpoints.api에 여러 인수를 제공할 수 있습니다. 사용 가능한 인수는 다음 표와 같습니다.

@endpoints.api 인수 설명 예시
allowed_client_ids API에서 인증을 사용하는 경우 필수 항목입니다. 토큰을 요청할 수 있는 클라이언트의 클라이언트 ID 목록입니다. 자세한 내용은 허용되는 클라이언트 ID 및 대상을 참조하세요. allowed_client_ids=['1-web-apps.apps.googleusercontent.com','2-android-apps.apps.googleusercontent.com', endpoints.API_EXPLORER_CLIENT_ID]
api_key_required 선택사항. API 키를 제공하는 요청에 대한 액세스를 제한하는 데 사용됩니다. api_key_required=True
audiences API에 인증이 필요하고 Android 클라이언트를 지원하는 경우 필수 항목입니다. Google ID 토큰의 경우, 이는 토큰 요청을 위임한 클라이언트 ID의 목록일 수 있습니다. 제3자 인증 제공업체(예: Auth0)가 토큰을 발급하는 경우, 이는 인증 발급기관 이름과 대상 목록 간의 사전 매핑이어야 합니다. 자세한 내용은 허용되는 클라이언트 ID 및 대상을 참조하세요. audiences=['1-web-apps.apps.googleusercontent.com'] 또는 audiences={"auth0": ["aud-1.auth0.com", "aud-2.auth0.com"]}
base_path 선택사항. 지정된 경로에서 API를 제공하는 데 사용됩니다. 이 인수를 지정하는 경우 app.yaml 파일의 handlers 섹션도 변경해야 합니다. 다른 경로에서 API 제공을 참조하세요.
canonical_name 선택사항. 클라이언트 라이브러리에서 API에 다른 이름이나 더 읽기 쉬운 이름을 지정하는 데 사용됩니다. 이 이름은 클라이언트 라이브러리에서 이름을 생성하는 데 사용되며 백엔드 API는 name 속성에 지정된 값을 계속 사용합니다.

예를 들어 API에 dfaanalytics로 설정된 name이 있는 경우 이 속성을 사용하여 DFA Group Analytics의 표준 이름을 지정할 수 있습니다. 그러면 생성된 클라이언트 클래스에 DfaGroupAnalytics 이름이 포함됩니다.

예시와 같이 이름 사이에 적절한 공백을 포함시켜야 합니다. 이러한 공백은 적절한 카멜표기법 또는 밑줄로 대체됩니다.
canonical_name='DFA Analytics'
description API에 대한 간단한 설명입니다. API 설명을 위해 검색 서비스에 노출되며, 클라이언트 라이브러리 생성에 설명된 대로 문서를 생성하는 데에도 사용 가능합니다. description='Sample API for a simple game'
documentation 선택사항. 사용자가 이 버전의 API에 대한 문서를 찾을 수 있는 URL입니다. 사용자가 서비스에 대해 알아볼 수 있도록 API 탐색기 페이지 상단에 '자세히 알아보기'로 강조표시됩니다. documentation='http://link_to/docs'
hostname App Engine 애플리케이션의 호스트 이름입니다. Endpoints Frameworks 명령줄 도구는 탐색 문서 또는 OpenAPI 문서를 생성할 때 개발자가 여기에서 지정하는 값을 사용합니다. 여기서 호스트 이름을 지정하지 않으면 호스트 이름을 app.yaml 파일의 application 필드에 지정하거나 App Engine 애플리케이션을 배포할 때 프로젝트 ID를 지정해야 합니다. hostname='your_app_id.appspot.com'
issuers 선택사항. 커스텀 JWT 발급기관 구성입니다. 이는 발급자 이름에서 endpoints.Issuer 객체로의 사전 매핑이어야 합니다. issuers={"auth0": endpoints.Issuer("https://test.auth0.com", "https://test.auth0.com/.well-known/jwks.json")}
name 필수 항목. API의 모든 메서드 및 경로에 대한 프리픽스로 사용되는 API의 이름입니다. name 값은 다음과 같아야 합니다.
  • 반드시 소문자로 시작해야 합니다.
  • 반드시 정규 표현식 [a-z]+[A-Za-z0-9]와 일치해야 합니다. 즉, 이름의 나머지 부분을 대문자와 소문자 또는 숫자로 구성할 수 있습니다.
단일 서비스의 일부로 여러 API를 배포하려면 모든 API 이름이 정규 표현식 [a-z][a-z0-9]{0,39}와 일치해야 합니다. 즉, 이름은 소문자로 시작해야 하며 나머지 문자는 소문자 또는 숫자로, 40자를 넘지 않아야 합니다.
name='yourApi' 또는 name='yourapi'
limit_definitions 선택사항. API의 할당량을 정의하는 데 사용됩니다. 자세한 내용은 limit_definitions를 참조하세요.
owner_domain 선택사항. API를 소유한 항목의 도메인 이름입니다. 이 API에 대해 생성될 때 클라이언트 라이브러리의 이름을 적절히 지정하기 위한 힌트를 제공하기 위해 owner_name과 함께 사용됩니다. 패키지 경로는 owner_domainpackage_path의 역입니다(제공된 경우). 기본값은 appid.apppost.com를 사용합니다. owner_domain='your-company.com'
owner_name 선택사항. API를 소유한 항목의 이름입니다. 이 API에 대해 생성될 때 클라이언트 라이브러리의 이름을 적절히 지정하기 위한 힌트를 제공하기 위해 owner_domain과 함께 사용됩니다. owner_name='Your-Company'
package_path 선택사항. 이 API가 속한 '패키지'의 범위를 더 구체적으로 명시하는 데 사용되며, 값은 API의 논리적 그룹을 지정하는 /로 구분됩니다.

예를 들어 cloud/platform으로 지정할 경우 클라이언트 라이브러리 경로가 cloud/platform/<ApiName>으로 설정되고 클라이언트 라이브러리 패키지는 cloud.plaform.<ApiName>으로 설정됩니다.
package_path='cloud/platform'
scopes 제공되지 않는 경우, 기본값은 OAuth에 필수인 이메일 범위(https://www.googleapis.com/auth/userinfo.email)입니다. 필요에 따라 이를 재정의하여 더 많은 OAuth 2.0 범위를 지정할 수 있습니다. @endpoints.method 데코레이터에 다른 범위를 지정하여 여기에서 특정 API 메서드에 지정된 범위를 재정의할 수도 있습니다. 그러나 여러 범위를 정의하고 지정된 범위 중 하나라도 토큰이 발급된 경우 범위 검사에 통과합니다. 여러 범위를 요청하려면 각 범위 사이에 공백을 넣어 단일 문자열을 지정하세요. scopes=['ss0', 'ss1 and_ss2']
title 선택사항. API 탐색기에 API 제목으로 표시되고 검색 및 디렉토리 서비스에 노출되는 텍스트입니다. title='My Backend API'
version 필수 항목. Cloud Endpoints 버전을 지정합니다. 이 값은 API의 경로에 나타납니다. SemVer 표준과 호환되는 버전 문자열을 지정하면 API를 배포할 때 API 경로에 주 버전 번호만 표시됩니다. 예를 들어 echo라는 이름의 2.1.0 버전인 API의 경로는 /echo/v2와 유사합니다. echo API를 버전 2.2.0으로 업데이트하고 이전 버전과 호환되는 변경사항을 배포하면 경로는 /echo/v2로 유지됩니다. 따라서 이전 버전과 호환되는 변경을 수행할 때 클라이언트의 기존 경로를 유지하면서 API 버전 번호를 업데이트할 수 있습니다. 하지만 브레이킹 체인지를 배포하는 것이기 때문에 echo API를 버전 3.0.0으로 업데이트하면 경로가 /echo/v3으로 변경됩니다. version='v1' 또는 version='2.1.0'

limit_definitions

API의 할당량을 정의하려면 선택사항인 limit_definitions 인수를 @endpoints.api에 지정합니다. 할당량을 구성하려면 다음을 수행해야 합니다.

  • 버전 2.4.5 이상의 Endpoints Frameworks 라이브러리를 설치합니다.
  • 할당량을 적용하고자 하는 각 메서드의 메서드 데코레이터metric_costs 인수를 추가합니다.

할당량 설정에 필요한 모든 단계는 할당량 구성을 참조하세요.

하나 이상의 LimitDefinition 인스턴스 목록을 다음과 같이 지정합니다.

quota_limits = [
              endpoints.LimitDefinition(
                "name",
                "Display name",
                limit)
]

LimitDefinition 인스턴스에는 다음 값이 필요합니다.

요소 설명
이름 API 요청 카운터의 이름입니다. 일반적으로 할당량을 고유하게 식별하는 요청 유형(예: 'read-requests' 또는 'write-requests')입니다.
표시 이름

Endpoints > 서비스 페이지의 할당량 탭에 할당량 식별을 위해 표시되는 텍스트입니다. 이 텍스트는 IAM 및 관리자와 API 및 서비스의 할당량 페이지를 통해 API 소비자에게도 표시됩니다. 표시 이름은 최대 40자여야 합니다.

읽기 쉽게 할당량 페이지의 표시 이름에 'per minute per project'라는 텍스트가 자동으로 추가됩니다. API의 소비자가 보는 할당량 페이지에 나열되는 Google 서비스의 표시 이름과 일관성을 유지하기 위해 표시 이름에 대해 다음이 권장됩니다.

  • 하나의 측정항목만 있을 때는 'Requests'를 사용합니다.
  • 측정항목이 여러 개일 때는 각 측정항목에 요청의 유형과 'requests'라는 단어를 포함해야 합니다(예: 'Read requests' 또는 'Write requests').
  • 이 할당량의 비용이 1보다 크면 'Requests' 대신 'Quota units'를 사용합니다.

limit 할당량에 대한 소비자 프로젝트당 분당 최대 요청 수인 정수 값입니다.

quota_limits = [
  endpoints.LimitDefinition('read-requests', 'Read Requests', 1000),
  endpoints.LimitDefinition('list-requests', 'List Requests', 100),
  endpoints.LimitDefinition('write-requests', 'Write Requests', 50)
]

@endpoints.api(name='bookstore',
               version='v1',
               limit_definitions=quota_limits)

허용되는 클라이언트 ID 및 대상

OAuth2 인증의 경우 특정 클라이언트 ID에 OAuth2 토큰이 발급되어, 이 클라이언트 ID를 통해 API에 대한 액세스를 제한할 수 있습니다. Google Cloud 콘솔에서 Android 애플리케이션을 등록할 때 이에 대한 클라이언트 ID를 만듭니다. 이 클라이언트 ID가 인증을 위해 Google로부터 OAuth2 토큰을 요청하는 ID입니다. 백엔드 API가 인증으로 보호되면 OAuth2 액세스 토큰이 전송되어 App Engine용 Cloud Endpoints Frameworks에서 열리고, 토큰에서 클라이언트 ID가 추출된 다음 백엔드의 선언된 허용 가능 클라이언트 ID 목록(allowed_client_ids 목록)과 비교됩니다.

allowed_client_ids 목록은 웹, Android, 기타 클라이언트 앱에 대해 Google Cloud 콘솔을 통해 얻은 모든 클라이언트 ID로 구성됩니다. 즉, API 빌드 시 클라이언트가 알려져 있어야 합니다. 빈 목록을 지정하면 클라이언트가 절대 API에 액세스할 수 없습니다.

올바른 인증을 확인하고자 하는 각 API 메서드에서 endpoints.get_current_user()를 호출해야 합니다. 자세한 내용은 사용자 인증을 참조하세요.

allowed_client_ids 인수를 사용하며, API 탐색기를 사용하여 API에 대한 인증된 호출을 테스트하려는 경우에는 상수 endpoints.API_EXPLORER_CLIENT_ID를 지정하여 allowed_client_ids 목록으로 클라이언트 ID를 제공해야 합니다. allowed_client_idsendpoints.API_EXPLORER_CLIENT_ID만 포함된 경우 API를 배포하면 API를 공개적으로 검색할 수 있으며 API 탐색기에서 공개적으로 액세스할 수 있습니다.

대상 정보

allowed_client_ids 목록은 승인되지 않은 클라이언트로부터 백엔드 API를 보호합니다. 그러나 원하는 백엔드 API에만 인증 토큰이 작동하도록 클라이언트를 보호하기 위해서는 추가적인 보호 조치가 필요합니다. Android 클라이언트의 경우 이 메커니즘은 audiences 인수로, 여기에서 백엔드 API의 클라이언트 ID를 지정합니다.

Google Cloud 콘솔 프로젝트를 만들 때 기본 클라이언트 ID가 자동으로 생성되고 프로젝트에서 사용할 수 있도록 이름이 지정됩니다. App Engine에 백엔드 API를 업로드하면 해당 클라이언트 ID가 사용됩니다. 이는 API 인증에 언급된 웹 클라이언트 ID입니다.

제3자 인증 토큰 발급기관

Google ID 토큰이 아닌 제3자 발급기관에서 발급한 인증 토큰을 애플리케이션에서 허용하는 경우에는 @endpoints.api에서 audiencesissuers 인수를 제3자 발급기관에 대한 정보를 제공할 수 있도록 설정해야 합니다. 예를 들면 다음과 같습니다.

@endpoints.api(
        audiences={'auth0': ['aud-1.auth0.com', 'aud-2.auth0.com']},
        issuers={'auth0': endpoints.Issuer('https://test.auth0.com',
                                           'https://test.auth0.com/.well-known/jwks.json')})
class GreetingApi(remote.Service):

API 메서드 정의하기(@endpoints.method)

전체 API의 경우 @endpoints.api를, 메서드의 경우 @endpoints.method를 사용하여 audiences, scopes, allowed_client_ids 설정을 지정할 수 있습니다. API와 메서드 레벨 모두에 이러한 설정을 지정하는 경우 메서드 설정이 우선합니다.

API에서 메서드를 만들려면 해당 Python 메서드를 @endpoints.method로 데코레이션하여 메서드의 사용을 구성하는 인수를 제공합니다. 예를 들어 사용할 요청 및 응답 Message 클래스를 지정합니다.

사용 가능한 인수는 다음 표와 같습니다.

@endpoints.method 인수 설명
allowed_client_ids 이 설정은 @endpoints.api에 지정된 해당 속성을 재정의합니다. 자세한 내용은 허용되는 클라이언트 ID 및 대상을 참조하세요. ['1-web-apps.apps.googleusercontent.com', '2-android-apps.apps.googleusercontent.com']
api_key_required 선택사항. API 키를 제공하는 요청에 대한 액세스를 제한하는 데 사용됩니다. api_key_required=True
audiences @endpoints.api에 지정된 해당 인수를 재정의합니다. 자세한 내용은 허용되는 클라이언트 ID 및 대상을 참조하세요. ['1-web-apps.apps.googleusercontent.com']
metric_costs 선택사항. 메서드에 할당량 한도가 있음을 나타냅니다. 이는 다음 키-값 쌍이 포함된 사전입니다.
  • name: API 데코레이터에 대한 limit_definitions 인수에 지정한 이름입니다.
  • cost: 각 요청의 비용을 지정하는 정수입니다. 비용은 메서드가 동일 할당량에서 서로 다른 속도로 소비할 수 있게 해 줍니다. 예를 들어 할당량의 한도가 1,000이고 cost가 1이면 호출하는 애플리케이션이 한도를 넘기 전에 분당 1,000개의 요청을 할 수 있습니다. 동일한 할당량에 대해 cost가 2인 경우 호출하는 애플리케이션이 한도를 넘기 전에 분당 500개의 요청만 할 수 있습니다.
metric_costs={'read-requests': 1}
http_method 사용할 HTTP 메서드입니다. 이 인수를 설정하지 않으면 기본값으로 'POST'가 사용됩니다. 'GET'
name 이 메서드의 대체 이름입니다. name 값은 다음과 같아야 합니다.
  • 반드시 소문자로 시작해야 합니다.
  • 반드시 정규 표현식 [a-z]+[A-Za-z0-9]*와 일치해야 합니다.
'yourApi'
path 이 메서드에 액세스할 수 있는 URI 경로입니다. 이 인수를 설정하지 않으면 Python 메서드 이름이 사용됩니다. API 관리를 추가할 계획이면 경로에 후행 슬래시를 포함시키지 마세요. 'yourapi/path'
Request Message 클래스 메서드 호출에 사용할 Google 프로토콜 RPC Request Message 클래스입니다. 또는 클래스의 이름을 제공할 수 있습니다. YourRequestClass
Response Message 클래스 메서드 호출에 사용할 Google 프로토콜 RPC Response Message 클래스입니다. 또는 클래스의 이름을 제공할 수 있습니다. YourResponseClass

경로 또는 쿼리 문자열 인수에 ResourceContainer 사용

요청에 경로 또는 쿼리 문자열 인수가 포함된 경우에는 API 작성에 설명된 간단한 Message 클래스를 사용할 수 없습니다. 대신 다음과 같이 ResourceContainer 클래스를 사용해야 합니다.

  1. 요청 본문을 통해 전달되는 모든 인수가 들어 있는 Message 클래스를 정의합니다. 요청 본문에 인수가 없는 경우에는 Message 클래스를 정의할 필요 없이 그냥 message_types.VoidMessage을 사용하면 됩니다. 예를 들면 다음과 같습니다.

    class Greeting(messages.Message):
        """Greeting that stores a message."""
    
        message = messages.StringField(1)
  2. ResourceContainer을, 이전 단계에서 첫 번째 매개변수로 정의한 Message 클래스로 정의합니다. 다음 매개변수에서 경로 및 쿼리 문자열 인수를 지정합니다. 예를 들면 다음과 같습니다.

    MULTIPLY_RESOURCE = endpoints.ResourceContainer(
        Greeting,
        times=messages.IntegerField(2, variant=messages.Variant.INT32, required=True),

    여기서 첫 번째 인수는 요청 본문의 데이터에 대한 Message 클래스이고, times는 요청에 수반되는 경로 또는 쿼리 문자열에 예상되는 숫자입니다.

  3. 해당 위치에 제공되었을 요청 Message 클래스를 대체하는 첫 번째 매개변수에서, 요청을 처리하는 메서드에 ResourceContainer를 제공합니다. 다음 스니펫에서 ResourceContainerendpoints.method를 둘 다 확인할 수 있습니다.

    # This ResourceContainer is similar to the one used for get_greeting, but
    # this one also contains a request body in the form of a Greeting message.
    MULTIPLY_RESOURCE = endpoints.ResourceContainer(
        Greeting,
        times=messages.IntegerField(2, variant=messages.Variant.INT32, required=True),
    )
    
    @endpoints.method(
        # This method accepts a request body containing a Greeting message
        # and a URL parameter specifying how many times to multiply the
        # message.
        MULTIPLY_RESOURCE,
        # This method returns a Greeting message.
        Greeting,
        path="greetings/multiply/{times}",
        http_method="POST",
        name="greetings.multiply",
    )
    def multiply_greeting(self, request):
        return Greeting(message=request.message * request.times)
    
  4. 표시된 것과 같이 path 매개변수를 추가하여 API를 포함시킵니다.

  5. ResourceContainer에 필수 인수가 있으면, 클라이언트 요청의 쿼리 문자열(예: yourApi?times=2) 또는 URL 경로(예: yourApi/2)에 이 인수가 포함되어 있어야 합니다. 하지만 API가 URL 경로를 사용하여 인수 값을 수신하려면 path='yourApi/{times}{times} 인수에 대해 표시된 대로 API 경로에 인수 이름을 또한 추가해야 합니다.

다음 단계