

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# API Gateway 中用於 WebSocket API 的資料轉換
<a name="websocket-api-data-transformations"></a>

在 API Gateway 中，WebSocket API 的方法請求可視後端的需求，從對應的整合請求承載擷取不同格式的承載。同樣地，後端可能會依照前端的預期，傳回與方法回應承載不同的整合回應承載。

API Gateway 可讓您使用映射範本轉換，將承載從方法請求映射至對應的整合請求，以及從整合回應映射至對應的方法回應。您會建立映射範本並指定範本選擇表達式，以決定要使用哪個範本來執行必要的資料轉換。

您可以使用資料映射，將 [路由請求](api-gateway-basic-concept.md#apigateway-definition-route-request) 中的資料映射至後端整合。如需進一步了解，請參閱[設定 API Gateway 中 WebSocket API 的資料映射](websocket-api-data-mapping.md)。

## 對應範本和模型
<a name="apigateway-websocket-api-mapping-templats-and-models"></a>

 *對應範本*是以 [Velocity 範本語言 (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) 表示，並使用 [JSONPath 表達式](https://goessner.net/articles/JsonPath/)套用至承載的指令碼。如需 API Gateway 對應範本的詳細資訊，請參閱 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)。

根據 [JSON 結構描述草稿第 4 版](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04)，承載可以有一個*資料模型*。您不需要定義任何模型，即可建立對應範本。不過，模型可協助您建立範本，因為 API Gateway 會根據提供的模型產生範本藍圖。如需 API Gateway 模型的詳細資訊，請參閱 [REST API 的資料模型](models-mappings-models.md)。

## 範本選擇表達式
<a name="apigateway-websocket-api-template-selection-expressions"></a>

若要使用對應範本轉換承載，您可以[整合請求](apigateway-websocket-api-integration-requests.md)或[整合回應](apigateway-websocket-api-integration-responses.md)中指定 WebSocket API 範本選取運算式。此表達式的評估結果會判定輸入或輸出範本 (如有)，輸入範本可將請求本文轉換為整合請求本文，輸出範本則可將整合回應本文轉換為路由回應本文。

`Integration.TemplateSelectionExpression` 支援 `${request.body.jsonPath}` 和靜態值。

`IntegrationResponse.TemplateSelectionExpression` 支援 `${request.body.jsonPath}`、`${integration.response.statuscode}`、`${integration.response.header.headerName}`、`${integration.response.multivalueheader.headerName}` 和靜態值。

## 整合回應選擇表達式
<a name="apigateway-websocket-api-integration-response-selection-expressions"></a>

[設定 WebSocket API 的整合回應](apigateway-websocket-api-integration-responses.md)時，您可選擇指定整合回應選擇表達式。此運算式會判定整合回傳時應選取的 `[https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid-integrationresponses-integrationresponseid.html](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid-integrationresponses-integrationresponseid.html)`。此表達式的值目前正受 API Gateway 限制，規則如下。請注意，此表達式只與*非代理整合*有關；代理整合只要將回應承載回傳給發起人即可，無須建模或修改。

此表達式與上述選擇表達式不同，目前支援*模式比對*格式。此表達式應以斜線包裝。

目前固定的值視 `[https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html#apis-apiid-integrations-integrationid-prop-integration-integrationtype](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html#apis-apiid-integrations-integrationid-prop-integration-integrationtype)` 而異：
+ 若是 Lambda 型整合，此值為 `$integration.response.body.errorMessage`。
+ 若是 `HTTP` 及 `MOCK` 整合，此值為 `$integration.response.statuscode`。
+ 若是 `HTTP_PROXY` 及 `AWS_PROXY`，將不會運用此表達式，因為您請求將承載傳遞給發起人。

# 設定 API Gateway 中 WebSocket API 的資料映射
<a name="websocket-api-data-mapping"></a>

*資料映射*可讓您將[路由請求](api-gateway-basic-concept.md#apigateway-definition-route-request)中的資料映射至後端整合。

**注意**  
不支援 WebSocket APIs的資料映射 AWS 管理主控台。您必須使用 AWS CLI AWS CloudFormation、 或 SDK 來設定資料映射。

**Topics**
+ [將路由請求資料對應到整合請求參數](#websocket-mapping-request-parameters)
+ [範例](#websocket-data-mapping-examples)

## 將路由請求資料對應到整合請求參數
<a name="websocket-mapping-request-parameters"></a>

整合請求參數可以從任何定義的路由請求參數，請求內文、[`context`](api-gateway-mapping-template-reference.md#context-variable-reference) 或 [`stage`](api-gateway-mapping-template-reference.md#stagevariables-template-reference) 的變量，以及靜態值進行映射。

下表展示整合請求資料映射表達式。在下表中，*`PARAM_NAME`* 是指定參數類型的路由請求參數的名稱。它必須符合規則表達式 `'^[a-zA-Z0-9._$-]+$]'`。*JSONPath\$1EXPRESSION* 是請求內文的 JSON 欄位的 JSONPath 表達式。


| 映射的資料來源 | 對應表達式 | 
| --- | --- | 
| 請求查詢字串 (僅支援 \$1connect 路由) | route.request.querystring.PARAM\$1NAME | 
| 請求標頭 (僅支援 \$1connect 路由) | route.request.header.PARAM\$1NAME | 
| 多值請求查詢字串 (僅支援 \$1connect 路由) | route.request.multivaluequerystring.PARAM\$1NAME | 
| 多值請求標頭 (僅支援 \$1connect 路由) | route.request.multivalueheader.PARAM\$1NAME | 
| 請求內文 | route.request.body.JSONPath\$1EXPRESSION | 
| 階段變數 | stageVariables.VARIABLE\$1NAME | 
| 環境變數 | context.VARIABLE\$1NAME 必須是[支援的環境變數](api-gateway-mapping-template-reference.md#context-variable-reference)之一。 | 
| 靜態值 | 'STATIC\$1VALUE'。STATIC\$1VALUE 是字串常值，而且必須以一對單引號括住。 | 

當您建立資料映射時，使用 AWS CLI 時，請務必遵循在 中使用常值與字串的正確格式 AWS CLI。如需詳細資訊，請參閱《AWS Command Line Interface 使用者指南》**中的[搭配 AWS CLI中的字串使用引號和常值](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-quoting-strings.html)。

## 範例
<a name="websocket-data-mapping-examples"></a>

下列 AWS CLI 範例會設定資料映射。如需範例 CloudFormation 範本，請參閱 [samples/websocket-data-mapping.zip](samples/websocket-data-mapping.zip)。

### 將用戶端的連線 ID 映射至整合請求中的標頭
<a name="websocket-data-mapping-examples.connectionId"></a>

以下 [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-integration.html) 命令會將用戶端的 `connectionId` 映射至後端整合請求中的 `connectionId` 標頭：

```
aws apigatewayv2 update-integration \
    --integration-id abc123 \
    --api-id a1b2c3d4 \ 
    --request-parameters 'integration.request.header.connectionId'='context.connectionId'
```

### 將查詢字串參數映射至整合請求中的標頭
<a name="websocket-data-mapping-examples.querystring"></a>

下列範例會將 `authToken` 查詢字串參數映射至整合請求中的 `authToken` 標頭。

1. 使用下列 [update-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-route.html) 命令，將 `authToken` 查詢字串參數新增至路由的請求參數。

   ```
   aws apigatewayv2 update-route --route-id 0abcdef \
       --api-id a1b2c3d4 \
       --request-parameters '{"route.request.querystring.authToken": {"Required": false}}'
   ```

1.  使用下列 [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-integration.html) 命令，將查詢字串參數映射至後端整合請求中的 `authToken` 標頭。

   ```
   aws apigatewayv2 update-integration \
       --integration-id abc123 \
       --api-id a1b2c3d4 \
       --request-parameters 'integration.request.header.authToken'='route.request.querystring.authToken'
   ```

1. (選用) 如有必要，使用下列 [delete-route-request-parameter](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/delete-route-request-parameter.html) 從路由的請求參數中刪除 `authToken` 查詢字串參數。

   ```
   aws apigatewayv2 delete-route-request-parameter \
       --route-id 0abcdef \
       --api-id a1b2c3d4 \
       --request-parameter-key 'route.request.querystring.authToken'
   ```

# 用於 API Gateway 的 WebSocket API 映射範本參考
<a name="apigateway-websocket-api-mapping-template-reference"></a>

此章節摘要說明目前 API Gateway 內 WebSocket API 支援的變數組。


| 參數 | 描述 | 
| --- | --- | 
| \$1context.connectionId |  連線的唯一 ID，可用來回呼用戶端。  | 
| \$1context.connectedAt |  [Epoch](https://en.wikipedia.org/wiki/Unix_time) 格式化連線時間。  | 
| \$1context.domainName |  WebSocket API 的網域名稱。此可用於回呼用戶端 (非硬式編碼的值)。  | 
| \$1context.eventType |  事件類型：`CONNECT`、`MESSAGE` 或 `DISCONNECT`。  | 
| \$1context.messageId |  訊息的伺服器端唯一 ID。僅在 `$context.eventType` 為 `MESSAGE` 時可用。  | 
| \$1context.routeKey |  所選路由金鑰。  | 
| \$1context.requestId |  與 `$context.extendedRequestId` 相同。  | 
| \$1context.extendedRequestId | API 呼叫的自動產生的 ID，其中包含更多除錯/故障排除的有用的資訊。 | 
| \$1context.apiId |  API Gateway 指派給您 API 的識別碼。  | 
| \$1context.authorizer.principalId |  與用戶端所傳送並從 API Gateway Lambda 授權方 (先前稱作自訂授權方) Lambda 函數所傳回之權杖建立關聯的主要使用者識別。  | 
| \$1context.authorizer.property |  API Gateway Lambda 授權方函數所傳回 `context` 映射之指定索引鍵/值組的字串化值。例如，如果授權方傳回下列 `context` 映射： <pre>"context" : {<br />  "key": "value",<br />  "numKey": 1,<br />  "boolKey": true<br />}</pre> 呼叫 `$context.authorizer.key` 會傳回 `"value"` 字串、呼叫 `$context.authorizer.numKey` 會傳回 `"1"` 字串，而呼叫 `$context.authorizer.boolKey` 會傳回 `"true"` 字串。  | 
| \$1context.error.messageString | \$1context.error.message 的引用值，即 "\$1context.error.message"。 | 
| \$1context.error.validationErrorString |  字串，其中包含詳細的驗證錯誤訊息。  | 
| \$1context.identity.accountId |  與請求相關聯的 AWS 帳戶 ID。  | 
| \$1context.identity.apiKey |  與啟用金鑰之 API 請求建立關聯的 API 擁有者金鑰。  | 
| \$1context.identity.apiKeyId | 與啟用金鑰之 API 請求建立關聯的 API 金鑰 ID。 | 
| \$1context.identity.caller |  提出請求之發起人的委託人識別符。  | 
| \$1context.identity.cognitoAuthenticationProvider |  提出請求的發起人所使用的所有 Amazon Cognito 驗證提供者清單 (以逗號分隔)。僅在使用 Amazon Cognito 登入資料簽署請求時才可使用。 例如，適用於 Amazon Cognito 使用者集區的身分，`cognito-idp. region.amazonaws.com/user_pool_id,cognito-idp.region.amazonaws.com/user_pool_id:CognitoSignIn:token subject claim` 如需有關 Amazon Cognito 驗證提供者的詳細資訊，請參閱《[Amazon Cognito 開發人員指南](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html)》中的*使用聯合身分*。 | 
| \$1context.identity.cognitoAuthenticationType |  提出請求的發起人的 Amazon Cognito 驗證類型。僅在使用 Amazon Cognito 登入資料簽署請求時才可使用。可能的值包括用於已驗證身分的 `authenticated` 和未經驗證身分的 `unauthenticated`。 | 
| \$1context.identity.cognitoIdentityId |  提出請求的發起人的 Amazon Cognito 身分 ID。僅在使用 Amazon Cognito 登入資料簽署請求時才可使用。  | 
| \$1context.identity.cognitoIdentityPoolId |  提出請求的發起人的 Amazon Cognito 身分集區 ID。僅在使用 Amazon Cognito 登入資料簽署請求時才可使用。  | 
| \$1context.identity.sourceIp |  對 API Gateway 提出請求之即時 TCP 連線的來源 IP 地址。  | 
| \$1context.identity.user |  提出請求之使用者的委託人識別符。  | 
| \$1context.identity.userAgent |  API 發起人的使用者代理程式。  | 
| \$1context.identity.userArn |  身分驗證之後識別之有效使用者的 Amazon Resource Name (ARN)。  | 
| \$1context.requestTime | [CLF](https://httpd.apache.org/docs/current/logs.html#common) 格式化請求時間 (dd/MMM/yyyy:HH:mm:ss \$1-hhmm)。 | 
| \$1context.requestTimeEpoch | [Epoch](https://en.wikipedia.org/wiki/Unix_time) 格式化的要求時間，以毫秒為單位。 | 
| \$1context.stage |  API 呼叫的部署階段 (例如，Beta 或 Prod)。  | 
| \$1context.status |  回應狀態。  | 
| \$1input.body | 傳回原始承載作為字串。 | 
| \$1input.json(x) | 此函數會評估 JSONPath 表達式，並傳回結果作為 JSON 字串。 例如，`$input.json('$.pets')` 會傳回代表 pets 結構的 JSON 字串。 如需 JSONPath 的詳細資訊，請參閱 [JSONPath](https://goessner.net/articles/JsonPath/) 或[適用於 Java 的 JSONPath](https://github.com/json-path/JsonPath)。 | 
| \$1input.path(x) | 採用 JSONPath 表達式字串 (`x`)，並傳回結果的 JSON 物件呈現。這可讓您存取和運用 [Apache Velocity 範本語言 (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) 中原生承載的元素。 例如，如果表達式 `$input.path('$.pets')` 傳回如下物件： <pre>[<br />  { <br />    "id": 1, <br />    "type": "dog", <br />    "price": 249.99 <br />  }, <br />  { <br />    "id": 2, <br />    "type": "cat", <br />    "price": 124.99 <br />  }, <br />  { <br />    "id": 3, <br />    "type": "fish", <br />    "price": 0.99 <br />  } <br />]</pre> `$input.path('$.pets').count()` 會傳回 `"3"`。 如需 JSONPath 的詳細資訊，請參閱 [JSONPath](http://goessner.net/articles/JsonPath/) 或[適用於 Java 的 JSONPath](https://github.com/jayway/JsonPath)。 | 
| \$1stageVariables.<variable\$1name> |  *<variable\$1name>* 代表階段變數名稱。  | 
| \$1stageVariables['<variable\$1name>'] |  *<variable\$1name>* 代表任何階段變數名稱。  | 
| \$1\$1stageVariables['<variable\$1name>']\$1 |  *<variable\$1name>* 代表任何階段變數名稱。  | 
| \$1util.escapeJavaScript() |  使用 JavaScript 字串規則來逸出字串中的字元。  此函數會將任何一般單引號 (`'`) 轉換為逸出單引號 (`\'`)。不過，逸出單引號不適用於 JSON。因此，將此函數的輸出用於 JSON 屬性時，您必須將任何逸出單引號 (`\'`) 轉換為一般單引號 (`'`)。下列範例顯示這種情況： <pre> $util.escapeJavaScript(data).replaceAll("\\'","'")</pre>   | 
| \$1util.parseJson() |   採用「字串化」JSON，並傳回結果的物件呈現。您可以使用此函數的結果，來存取和運用 Apache Velocity 範本語言 (VTL) 中原生承載的元素。例如，如果您有下列承載： <pre>{"errorMessage":"{\"key1\":\"var1\",\"key2\":{\"arr\":[1,2,3]}}"}</pre>  並使用下列映射範本  <pre>#set ($errorMessageObj = $util.parseJson($input.path('$.errorMessage')))<br />{<br />   "errorMessageObjKey2ArrVal" : $errorMessageObj.key2.arr[0]<br />}<br /></pre> 您將會收到下列輸出： <pre>{<br />   "errorMessageObjKey2ArrVal" : 1<br />}<br /></pre>  | 
| \$1util.urlEncode() | 將字串轉換為 "application/x-www-form-urlencoded" 格式。 | 
| \$1util.urlDecode() | 解碼 "application/x-www-form-urlencoded" 字串。 | 
| \$1util.base64Encode() | 將資料編碼為 base64 編碼字串。 | 
| \$1util.base64Decode() | 解碼 base64 編碼字串中的資料。 | 