

# Data transformations for WebSocket APIs in API Gateway
<a name="websocket-api-data-transformations"></a>

In API Gateway, a WebSocket API's method request can take a payload in a different format from the corresponding integration request payload, as required in the backend. Similarly, the backend may return an integration response payload different from the method response payload, as expected by the frontend. 

API Gateway lets you use mapping template transformations to map the payload from a method request to the corresponding integration request and from an integration response to the corresponding method response. You create a mapping template and You specify a template selection expression to determine which template to use to perform the necessary data transformations.

You can use data mappings to map data from a [route request](api-gateway-basic-concept.md#apigateway-definition-route-request) to a backend integration. To learn more, see [Set up data mapping for WebSocket APIs in API Gateway](websocket-api-data-mapping.md).

## Mapping templates and models
<a name="apigateway-websocket-api-mapping-templats-and-models"></a>

 A *mapping template* is a script expressed in [Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) and applied to the payload using [JSONPath expressions](https://goessner.net/articles/JsonPath/). For more information about API Gateway mapping templates, see [Mapping template transformations for REST APIs in API Gateway](models-mappings.md).

The payload can have a *data model* according to the [JSON schema draft 4](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04). You do not have to define a model to create a mapping template. However, a model can help you create a template because API Gateway generates a template blueprint based on a provided model. For more information about API Gateway models, see [Data models for REST APIs](models-mappings-models.md).

## Template selection expressions
<a name="apigateway-websocket-api-template-selection-expressions"></a>

To transform a payload with a mapping template, you specify a WebSocket API template selection expression in an [integration request](apigateway-websocket-api-integration-requests.md) or [integration response](apigateway-websocket-api-integration-responses.md). This expression is evaluated to determine the input or output template (if any) to use to transform either the request body into the integration request body (via an input template) or the integration response body to the route response body (via an output template).

`Integration.TemplateSelectionExpression` supports `${request.body.jsonPath}` and static values.

`IntegrationResponse.TemplateSelectionExpression` supports `${request.body.jsonPath}`, `${integration.response.statuscode}`, `${integration.response.header.headerName}`, `${integration.response.multivalueheader.headerName}`, and static values.

## Integration response selection expressions
<a name="apigateway-websocket-api-integration-response-selection-expressions"></a>

When you [set up an integration response](apigateway-websocket-api-integration-responses.md) for a WebSocket API, you can optionally specify an integration response selection expression. This expression determines what `[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)` should be selected when an integration returns. The value of this expression is currently restricted by API Gateway, as defined below. Realize that this expression is only relevant for *non-proxy integrations*; a proxy integration simply passes the response payload back to the caller without modeling or modification.

Unlike the other preceding selection expressions, this expression currently supports a *pattern-matching* format. The expression should be wrapped with forward slashes.

Currently the value is fixed depending on the `[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)`:
+ For Lambda-based integrations, it is `$integration.response.body.errorMessage`.
+ For `HTTP` and `MOCK` integrations, it is `$integration.response.statuscode`.
+ For `HTTP_PROXY` and `AWS_PROXY`, the expression isn't utilized because you're requesting that the payload pass through to the caller.

# Set up data mapping for WebSocket APIs in API Gateway
<a name="websocket-api-data-mapping"></a>

*Data mapping* enables you to map data from a [route request](api-gateway-basic-concept.md#apigateway-definition-route-request) to a backend integration.

**Note**  
Data mapping for WebSocket APIs isn't supported in the AWS Management Console. You must use the AWS CLI, AWS CloudFormation, or an SDK to configure data mapping.

**Topics**
+ [Map route request data to integration request parameters](#websocket-mapping-request-parameters)
+ [Examples](#websocket-data-mapping-examples)

## Map route request data to integration request parameters
<a name="websocket-mapping-request-parameters"></a>

Integration request parameters can be mapped from any defined route request parameters, the request body, [`context` or ](api-gateway-mapping-template-reference.md#context-variable-reference) [`stage`](api-gateway-mapping-template-reference.md#stagevariables-template-reference) variables, and static values.

The following table shows integration request data mapping expressions. In the table, *`PARAM_NAME`* is the name of a route request parameter of the given parameter type. It must match the regular expression `'^[a-zA-Z0-9._$-]+$]'`. *JSONPath\$1EXPRESSION* is a JSONPath expression for a JSON field of the request body.


| Mapped data source | Mapping expression | 
| --- | --- | 
| Request query string (supported only for the \$1connect route) | route.request.querystring.PARAM\$1NAME | 
| Request header (supported only for the \$1connect route) | route.request.header.PARAM\$1NAME | 
| Multi-value request query string (supported only for the \$1connect route) | route.request.multivaluequerystring.PARAM\$1NAME | 
| Multi-value request header (supported only for the \$1connect route) | route.request.multivalueheader.PARAM\$1NAME | 
| Request body | route.request.body.JSONPath\$1EXPRESSION | 
| Stage variables | stageVariables.VARIABLE\$1NAME | 
| Context variables | context.VARIABLE\$1NAME that must be one of the [supported context variables](api-gateway-mapping-template-reference.md#context-variable-reference). | 
| Static value | 'STATIC\$1VALUE'. The STATIC\$1VALUE is a string literal and must be enclosed in single quotes. | 

When you create a data mapping, using the AWS CLI make sure to follow the correct format for using literals with strings in the AWS CLI. For more information, see [Using quotation marks and literals with strings in the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-quoting-strings.html) in the *AWS Command Line Interface User Guide*.

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

The following AWS CLI examples configure data mappings. For an example CloudFormation template, see [samples/websocket-data-mapping.zip](samples/websocket-data-mapping.zip).

### Map a client's connectionId to a header in an integration request
<a name="websocket-data-mapping-examples.connectionId"></a>

The following [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-integration.html) command maps a client's `connectionId` to a `connectionId` header in the request to a backend integration:

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

### Map a query string parameter to a header in an integration request
<a name="websocket-data-mapping-examples.querystring"></a>

The following example maps an `authToken` query string parameter to an `authToken` header in the integration request.

1. Use the following [update-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-route.html) command to add the `authToken` query string parameter to the route's request parameters.

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

1.  Use the following [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-integration.html) command to map the query string parameter to the `authToken` header in the request to the backend integration.

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

1. (Optional) If necessary, use the following [delete-route-request-parameter](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/delete-route-request-parameter.html) to delete the `authToken` query string parameter from the route's request parameters.

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

# WebSocket API mapping template reference for API Gateway
<a name="apigateway-websocket-api-mapping-template-reference"></a>

This section summarizes the set of variables that are currently supported for WebSocket APIs in API Gateway.


| Parameter | Description | 
| --- | --- | 
| \$1context.connectionId |  A unique ID for the connection that can be used to make a callback to the client.  | 
| \$1context.connectedAt |  The [Epoch](https://en.wikipedia.org/wiki/Unix_time)-formatted connection time.  | 
| \$1context.domainName |  A domain name for the WebSocket API. This can be used to make a callback to the client (instead of a hard-coded value).  | 
| \$1context.eventType |  The event type: `CONNECT`, `MESSAGE`, or `DISCONNECT`.  | 
| \$1context.messageId |  A unique server-side ID for a message. Available only when the `$context.eventType` is `MESSAGE`.  | 
| \$1context.routeKey |  The selected route key.  | 
| \$1context.requestId |  Same as `$context.extendedRequestId`.  | 
| \$1context.extendedRequestId | An automatically generated ID for the API call, which contains more useful information for debugging/troubleshooting. | 
| \$1context.apiId |  The identifier API Gateway assigns to your API.  | 
| \$1context.authorizer.principalId |  The principal user identification associated with the token sent by the client and returned from an API Gateway Lambda authorizer (formerly known as a custom authorizer) Lambda function.  | 
| \$1context.authorizer.property |  The stringified value of the specified key-value pair of the `context` map returned from an API Gateway Lambda authorizer function. For example, if the authorizer returns the following `context` map:  <pre>"context" : {<br />  "key": "value",<br />  "numKey": 1,<br />  "boolKey": true<br />}</pre> calling `$context.authorizer.key` returns the `"value"` string, calling `$context.authorizer.numKey` returns the `"1"` string, and calling `$context.authorizer.boolKey` returns the `"true"` string.  | 
| \$1context.error.messageString | The quoted value of \$1context.error.message, namely "\$1context.error.message". | 
| \$1context.error.validationErrorString |  A string containing a detailed validation error message.  | 
| \$1context.identity.accountId |  The AWS account ID associated with the request.  | 
| \$1context.identity.apiKey |  The API owner key associated with key-enabled API request.  | 
| \$1context.identity.apiKeyId | The API key ID associated with the key-enabled API request | 
| \$1context.identity.caller |  The principal identifier of the caller making the request.  | 
| \$1context.identity.cognitoAuthenticationProvider |  A comma-separated list of all the Amazon Cognito authentication providers used by the caller making the request. Available only if the request was signed with Amazon Cognito credentials.  For example, for an identity from an Amazon Cognito user pool, `cognito-idp. region.amazonaws.com/user_pool_id,cognito-idp.region.amazonaws.com/user_pool_id:CognitoSignIn:token subject claim` For information about the available Amazon Cognito authentication providers, see [Using Federated Identities](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html) in the *Amazon Cognito Developer Guide*. | 
| \$1context.identity.cognitoAuthenticationType |  The Amazon Cognito authentication type of the caller making the request. Available only if the request was signed with Amazon Cognito credentials. Possible values include `authenticated` for authenticated identities and `unauthenticated` for unauthenticated identities. | 
| \$1context.identity.cognitoIdentityId |  The Amazon Cognito identity ID of the caller making the request. Available only if the request was signed with Amazon Cognito credentials.  | 
| \$1context.identity.cognitoIdentityPoolId |  The Amazon Cognito identity pool ID of the caller making the request. Available only if the request was signed with Amazon Cognito credentials.  | 
| \$1context.identity.sourceIp |  The source IP address of the immediate TCP connection making the request to API Gateway endpoint.  | 
| \$1context.identity.user |  The principal identifier of the user making the request.  | 
| \$1context.identity.userAgent |  The User Agent of the API caller.  | 
| \$1context.identity.userArn |  The Amazon Resource Name (ARN) of the effective user identified after authentication.  | 
| \$1context.requestTime | The [CLF](https://httpd.apache.org/docs/current/logs.html#common)-formatted request time (dd/MMM/yyyy:HH:mm:ss \$1-hhmm). | 
| \$1context.requestTimeEpoch | The [Epoch](https://en.wikipedia.org/wiki/Unix_time)-formatted request time, in milliseconds. | 
| \$1context.stage |  The deployment stage of the API call (for example, Beta or Prod).  | 
| \$1context.status |  The response status.  | 
| \$1input.body | Returns the raw payload as a string. | 
| \$1input.json(x) | This function evaluates a JSONPath expression and returns the results as a JSON string. For example, `$input.json('$.pets')` will return a JSON string representing the pets structure. For more information about JSONPath, see [JSONPath](https://goessner.net/articles/JsonPath/) or [JSONPath for Java](https://github.com/json-path/JsonPath). | 
| \$1input.path(x) | Takes a JSONPath expression string (`x`) and returns a JSON object representation of the result. This allows you to access and manipulate elements of the payload natively in [Apache Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html). For example, if the expression `$input.path('$.pets')` returns an object like this: <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()` would return `"3"`. For more information about JSONPath, see [JSONPath](http://goessner.net/articles/JsonPath/) or [JSONPath for Java](https://github.com/jayway/JsonPath). | 
| \$1stageVariables.<variable\$1name> |  *<variable\$1name>* represents a stage variable name.  | 
| \$1stageVariables['<variable\$1name>'] |  *<variable\$1name>* represents any stage variable name.  | 
| \$1\$1stageVariables['<variable\$1name>']\$1 |  *<variable\$1name>* represents any stage variable name.  | 
| \$1util.escapeJavaScript() |  Escapes the characters in a string using JavaScript string rules.  This function will turn any regular single quotes (`'`) into escaped ones (`\'`). However, the escaped single quotes are not valid in JSON. Thus, when the output from this function is used in a JSON property, you must turn any escaped single quotes (`\'`) back to regular single quotes (`'`). This is shown in the following example:  <pre> $util.escapeJavaScript(data).replaceAll("\\'","'")</pre>   | 
| \$1util.parseJson() |   Takes "stringified" JSON and returns an object representation of the result. You can use the result from this function to access and manipulate elements of the payload natively in Apache Velocity Template Language (VTL). For example, if you have the following payload:  <pre>{"errorMessage":"{\"key1\":\"var1\",\"key2\":{\"arr\":[1,2,3]}}"}</pre>  and use the following mapping template  <pre>#set ($errorMessageObj = $util.parseJson($input.path('$.errorMessage')))<br />{<br />   "errorMessageObjKey2ArrVal" : $errorMessageObj.key2.arr[0]<br />}<br /></pre> You will get the following output: <pre>{<br />   "errorMessageObjKey2ArrVal" : 1<br />}<br /></pre>  | 
| \$1util.urlEncode() | Converts a string into "application/x-www-form-urlencoded" format. | 
| \$1util.urlDecode() | Decodes an "application/x-www-form-urlencoded" string. | 
| \$1util.base64Encode() | Encodes the data into a base64-encoded string. | 
| \$1util.base64Decode() | Decodes the data from a base64-encoded string. | 