如何使用 API Gateway 作為另一個 AWS 服務的代理?

5 分的閱讀內容
0

我想要使用 Amazon API Gateway 作為另一個 AWS 服務的代理,並將其他服務與 API Gateway 整合。

簡短說明

AWS 服務 API 本質上是您可以向其發出 HTTPS 請求的 REST API。您可以將許多 AWS 服務與 API Gateway 整合,但設定和映射會依據特定的服務 API 而有所不同。

若要將另一個服務與 API Gateway 整合,請建置一個從 API Gateway 至服務 API 的 HTTPS 請求。這樣,即可正確映射所有請求參數。

本文說明將 Amazon Simple Notification Service (Amazon SNS) Publish API 與 API Gateway 整合的範例設定。使用此範例作為整合其他服務的大綱。

解決方法

**注意:**如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤,請確定您使用的是最新的 AWS CLI 版本

設定所需的工具和資源

設定您的環境並建立您的使用案例需要的所有 AWS 資源。對於 Amazon SNS 範例設定,請執行下列動作:

  1. 安裝 AWS CLI
  2. 建立 Amazon SNS 主題。請注意主題的 Amazon Resource Name (ARN)。將在下一個步驟以及稍後在此設定中使用此資訊。
  3. 建立該主題的訂閱
  4. 開啟 AWS Identity and Access Management (IAM) 主控台,然後建立 AWS 服務代理執行角色。請注意角色的 ARN,以便稍後在設定中使用。此 IAM 角色授予 API Gateway 許可,讓其作為受信任的實體來承擔服務並執行您要整合的 API 動作。對於 Amazon SNS 範例設定,允許執行動作 sns:Publish。如需詳細資訊,請參閱用於調用 API 的 API Gateway 許可模型
  5. [使用測試資源建立 API Gateway REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html)。如需詳細資訊和範例,請參閱 Amazon API Gateway 教學課程和研討會
    注意:或者,使用下列範例 OpenAPI 2.0 (Swagger) 定義匯入 REST API。此選項會預先設定 Amazon SNS 範例設定的設定。請務必用 IAM 角色的 ARN 替換 arn:aws:iam::account-id:role/apigateway-sns-role。將區域替換為要在其中建立 REST API 的 AWS 區域。
{
  "swagger": "2.0",
  "info": {
    "version": "2019-10-09T14:10:24Z",
    "title": "aws-service-integration"
  },
  "basePath": "/dev",
  "schemes": [
    "https"
  ],
  "paths": {
    "/test": {
      "post": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "Message",
            "in": "query",
            "required": true,
            "type": "string"
          },
          {
            "name": "TopicArn",
            "in": "query",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::account-id:role/apigateway-sns-role",
          "uri": "arn:aws:apigateway:region:sns:action/Publish",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.querystring.TopicArn": "method.request.querystring.TopicArn",
            "integration.request.querystring.Message": "method.request.querystring.Message"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST",
          "type": "aws"
        }
      }
    }
  },
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}

獲得 HTTPS 請求範例

從您要整合的服務 API 提出的 HTTPS 請求範例可協助您在 API Gateway 中正確映射請求參數。若要獲得 HTTPS 請求範例,請執行下列其中一個動作:

查看 API 文件中的範例。對於 Amazon SNS Publish API,您可以參考服務的 API 參考以取得範例請求

https://sns.us-west-2.amazonaws.com/?Action=Publish
&TargetArn=arn%3Aaws%3Asns%3Aus-west-2%3A803981987763%3Aendpoint%2FAPNS_SANDBOX%2Fpushapp%2F98e9ced9-f136-3893-9d60-776547eafebb
&Message=%7B%22default%22%3A%22This+is+the+default+Message%22%2C%22APNS_SANDBOX%22%3A%22%7B+%5C%22aps%5C%22+%3A+%7B+%5C%22alert%5C%22+%3A+%5C%22You+have+got+email.%5C%22%2C+%5C%22badge%5C%22+%3A+9%2C%5C%22sound%5C%22+%3A%5C%22default%5C%22%7D%7D%22%7D
&Version=2010-03-31
&AUTHPARAMS

-或-

從 API 調用產生它。使用 AWS CLI 調用服務 API,然後分析輸出。針對您要整合的服務 API 判斷對應的 AWS CLI 命令,然後使用 --debug 選項執行測試請求。

**提示:**查看 AWS CLI 命令參考以尋找對應的 AWS CLI 命令。

對於 Amazon SNS 範例設定,請執行此命令:

**注意:**用 Amazon SNS 主題的 ARN 替換 arn:aws:sns:us-east-1:123456789012:test

$ aws sns publish --topic-arn arn:aws:sns:us-east-1:123456789012:test --message "hi" --debug

命令輸出包含 HTTPS 請求和傳遞的標頭。以下是所尋找內容的範例:

2018-11-22 11:56:39,647 - MainThread - botocore.client - DEBUG - Registering retry handlers for service: sns
2018-11-22 11:56:39,648 - MainThread - botocore.hooks - DEBUG - Event before-parameter-build.sns.Publish: calling handler <function generate_idempotent_uuid at 0x11093d320>
2018-11-22 11:56:39,649 - MainThread - botocore.endpoint - DEBUG - Making request for OperationModel(name=Publish) (verify_ssl=True) with params: {'body': {'Action': u'Publish', u'Message': u'hello', 'Version': u'2010-03-31', u'TopicArn': u'arn:aws:sns:us-east-1:123456789012:test'}, 'url': u'https://sns.us-east-1.amazonaws.com/', 'headers': {'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 'User-Agent': 'aws-cli/1.15.74 Python/2.7.14 Darwin/16.7.0 botocore/1.9.23'}, 'context': {'auth_type': None, 'client_region': 'us-east-1', 'has_streaming_input': False, 'client_config': <botocore.config.Config object at 0x1118437d0>}, 'query_string': '', 'url_path': '/', 'method': u'POST'}
2018-11-22 11:56:39,650 - MainThread - botocore.hooks - DEBUG - Event request-created.sns.Publish: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x111843750>>
2018-11-22 11:56:39,650 - MainThread - botocore.hooks - DEBUG - Event choose-signer.sns.Publish: calling handler <function set_operation_specific_signer at 0x11093d230>
2018-11-22 11:56:39,650 - MainThread - botocore.auth - DEBUG - Calculating signature using v4 auth.
2018-11-22 11:56:39,651 - MainThread - botocore.auth - DEBUG - CanonicalRequest:
POST
/

content-type:application/x-www-form-urlencoded; charset=utf-8
host:sns.us-east-1.amazonaws.com
x-amz-date:20181122T062639Z

content-type;host;x-amz-date

在此範例中,請求會以 POST HTTP 方法的形式傳送。

為您的 API Gateway API 建立方法

  1. API Gateway 主控台API 窗格中,選擇 API 的名稱。
  2. 資源窗格中,選擇一項資源。對於 Amazon SNS 範例設定,請選擇您建立的測試資源。
  3. 選擇動作,然後選擇建立方法
  4. 在下拉式清單中,在 HTTPS 請求範例中選擇您的服務 API 所使用的方法。(對於 Amazon SNS 範例設定,請選擇 POST。) 然後,選擇核取記號圖示。
  5. 設定窗格中,執行下列動作:
    對於整合類型,請選擇 AWS 服務
    對於 AWS 區域,請選擇與您要整合的服務 API 相關聯之資源的 AWS 區域。對於 Amazon SNS 範例設定,請選擇 SNS 主題的區域。
    對於 AWS 服務,請選擇要與 API Gateway 整合的服務。例如,Simple Notification Service (SNS)
    (選用) 對於 AWS 子網域,請輸入 AWS 服務使用的子網域。請查看服務的文件以確認子網域的可用性。對於 Amazon SNS 範例設定,請將其保留空白。
    對於 HTTP 方法,請選擇與您要整合的 AWS 服務 API 相對應的方法。對於 Amazon SNS 範例設定,請選擇 POST
    對於動作類型,如果您要整合的服務 API 是受支援的動作,請選擇使用動作名稱。請查看服務的 API 參考以取得支援的動作清單。對於 Amazon SNS,請參閱動作
    對於動作,請輸入服務 API 的名稱。對於 Amazon SNS 範例設定,請輸入 Publish
    -或-
    對於動作類型,如果 AWS 服務 API 希望您的請求中有資源路徑,請選擇使用路徑覆寫。例如,對於 Amazon Polly ListLexicons API,請為路徑覆寫 (選用) 輸入 /v1/lexicons
    對於執行角色,請輸入您建立的 IAM 角色的 ARN。
    (選用) 對於內容處理使用預設逾時,請根據需要對您的使用案例進行變更。對於 Amazon SNS 範例設定,請勿變更這些設定。
  6. 選擇儲存

為方法請求建立參數

針對您要整合的服務 API,判斷必要和選用的請求參數。若要識別這些參數,請參閱稍早取得的 HTTPS 請求範例,或參閱服務 API 的 API 參考。例如,參閱 Publish

  1. API Gateway 主控台中,在 API Gateway API 方法的方法執行窗格中,選擇方法請求
  2. (選用) 在方法請求窗格中,如果您要驗證查詢字串參數,對於請求驗證程式,請選擇請求驗證程式、內文和標頭。
  3. 展開 URL 查詢字串參數
  4. 選擇新增查詢字串
  5. 對於名稱,請輸入要整合之服務 API 的請求參數名稱。
  6. 選擇核取記號圖示 (建立新的查詢字串)。
  7. 如果該參數為必要參數,請選取必要下的核取方塊。
  8. 對您要包含的所有請求參數重複步驟 4-7。對於 Amazon SNS 範例設定,請建立名為 T****opicArn 的參數和另一個名為 Message 的參數。

如需詳細資訊,請參閱使用 API Gateway 主控台設定方法

注意:對於某些服務 API,除了必要的參數之外,您還必須在整合請求中傳送必要的標頭和內文。您可以在 HTTP 請求標題請求內文下的整合請求窗格中建立標頭和內文。

例如,如果您要整合 Amazon Rekognition ListCollections API,請建立標頭 X-Amz-Target: RekognitionService.ListCollections。該請求如下所示:

POST https://rekognition.us-west-2.amazonaws.com/ HTTP/1.1
    Host: rekognition.us-west-2.amazonaws.com
    Accept-Encoding: identity
    Content-Length: 2
    X-Amz-Target: RekognitionService.ListCollections
    X-Amz-Date: 20170105T155800Z
    User-Agent: aws-cli/1.11.25 Python/2.7.9 Windows/8 botocore/1.4.82
    Content-Type: application/x-amz-json-1.1
    Authorization: AWS4-HMAC-SHA256 Credential=XXXXXXXX/20170105/us-west-2/rekognition/aws4_request,
      SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=XXXXXXXX

    {}

如果您要整合 Amazon Simple Queue Service (Amazon SQS) SendMessage API,請使用映射表達式 method.request.body.JSONPath_EXPRESSION映射請求。(對於請求內文的 JSON 欄位,請將 JSONPath_EXPRESSION 替換為 JSONPath 表達式。) 在此範例中,請求類似下列內容:

{'url_path': '/', 'query_string': '', 'method': 'POST',
'headers': {'Content-Type': 'application/x-www-form-urlencoded;
charset=utf-8', 'User-Agent': 'aws-cli/1.16.81 Python/3.6.5 Darwin/18.7.0 botocore/1.12.183'},
'body': {'Action': 'SendMessage', 'Version': '2012-11-05', 'QueueUrl': 'https://sqs.ap-southeast-2.amazonaws.com/123456789012/test01', 'MessageBody': 'Hello'},
'url': 'https://ap-southeast-2.queue.amazonaws.com/', 'context': {'client_region': 'ap-southeast-2', 'client_config': <botocore.config.Config object at 0x106862da0>, 'has_streaming_input': False, 'auth_type': None}}

為整合請求建立參數

將您為方法請求建立的參數映射至整合請求的參數。

  1. API Gateway 主控台中,返回至 API Gateway API 方法的方法執行窗格,然後選擇整合請求
  2. 整合請求窗格中,展開 URL 查詢字串參數
  3. 選擇新增查詢字串
  4. 對於名稱,請輸入要整合之服務 API 的請求參數名稱。
    **注意:**該名稱區分大小寫,並且必須完全按照服務 API 的預期顯示。
  5. 對於映射自,請輸入 method.request.querystring.param_name。將 param_name 替換為您為方法請求建立的對應參數的名稱。例如,method.request.querystring.TopicArn
  6. 選擇核取記號圖示 (建立)。
  7. 重複步驟 3-6,為整合請求建立與您為方法請求建立的每個參數相對應的參數。

注意:如果您為方法請求建立了必要的標頭和內文,還請將它們映射到整合請求。在 HTTP 標頭映射範本下的整合請求窗格中建立標頭和內文。

如需詳細資訊,請參閱使用 API Gateway 主控台設定 API 整合請求

(選用) 檢查您的整合組態

若要確認整合設定是否如您預期,您可以執行 AWS CLI get-integration 命令來檢查類似下列內容的組態:

$ aws apigateway get-integration --rest-api-id 1234123412 --resource-id y9h6rt --http-method POST

對於 Amazon SNS 範例設定,輸出內容類似下列內容:

{
    "integrationResponses": {
        "200": {
            "responseTemplates": {
                "application/json": null
            },
            "statusCode": "200"
        }
    },
    "passthroughBehavior": "WHEN_NO_MATCH",
    "timeoutInMillis": 29000,
    "uri": "arn:aws:apigateway:us-east-2:sns:action/Publish",
    "httpMethod": "POST",
    "cacheNamespace": "y9h6rt",
    "credentials": "arn:aws:iam::1234567890:role/apigateway-sns-role",
    "type": "AWS",
    "requestParameters": {
        "integration.request.querystring.TopicArn": "method.request.querystring.TopicArn",
        "integration.request.querystring.Message": "method.request.querystring.Message"
    },
    "cacheKeyParameters": []
}

API Gateway 主控台中,返回至 API Gateway API 方法的方法執行窗格,然後選擇測試

  1. 方法測試窗格中,執行下列動作:
    對於查詢字串,請輸入包含請求參數和其值的查詢字串。對於 Amazon SNS 範例設定,請輸入 TopicArn= arn:aws:sns:us-east-1:123456789012:test&Message="Hello"。將 arn:aws:sns:us-east-1:123456789012:test 替換為 Amazon SNS 主題的 ARN。
    對於標頭請求內文,如果您為設定建立了這些內容,請輸入標頭名稱和請求內文 JSON。
    選擇測試。回應會顯示在方法測試窗格中。如果回應成功,您會看到狀態: 200。對於 Amazon SNS 範例設定,成功的回應會在回應內文中包含 MessageId
    如需詳細資訊,請參閱使用 API Gateway 主控台測試 REST API 方法
  2. 部署您的 REST API
  3. 使用您喜歡的任何工具測試您的 API。

相關資訊

教學課程: 使用 AWS 整合建置 API Gateway REST API

在 API Gateway 中設定 REST API 方法

設定 REST API 整合

使用 API Gateway 主控台設定請求與回應資料映射