J Mas
J Mas

Reputation: 150

How to change response from AWS StepFunction in API Gateway HTTP

I'm configuring API Gateway with HTTP -> Step Function -> Lambda, all work fine except I can't exclude some fields from the response getting from API Gateway or Step Function. Currently the response includes many unnecessary data.

{
  "billingDetails": {
    "billedDurationInMilliseconds": 100,
    "billedMemoryUsedInMB": 64
  },
  "executionArn": "arn:aws:states:us-west-2:***:express:ExpressStateMachine:********",
  "input": "{}",
  "inputDetails": {
    "__type": "com.amazonaws.swf.base.model#CloudWatchEventsExecutionDataDetails",
    "included": true
  },
  "name": "*********",
  "output": "{\"billedDurationInMilliseconds\":100,\"billedMemoryUsedInMB\":64}",
  "outputDetails": {
    "__type": "com.amazonaws.swf.base.model#CloudWatchEventsExecutionDataDetails",
    "included": true
  },
  "startDate": 1.667486785389E9,
  "stateMachineArn": "arn:aws:states:us-west-2:***:stateMachine:ExpressStateMachinePartnerMock",
  "status": "SUCCEEDED",
  "stopDate": 1.667486785466E9
}

I want in the body only the output as a JSON and specifically use HTTP not REST option in API Gateway, I was thinking as well using Lambda to StepFunction, but this is not acceptable since there are many stages in step function, I tried using response mapping in API Gateway but all I could do is put or rewrite data into header, it looks like I can map only header and response code. Is it possible to configure API Gateway so that body returned from StepFunction can be replaced.

Upvotes: 0

Views: 1091

Answers (1)

tannax
tannax

Reputation: 36

What you are looking for is in Integration Response of your method: Mapping Templates. It allowes you to modify the body of the response.

As you, I wanted to get ride of unwanted informations and have a better access to output data as JSON.

Here is a template you can start with:

#set($inputRoot = $input.path('$'))
{
  "name" : "$inputRoot.name",
  "output" : $inputRoot.output,
  "startDate" : $inputRoot.startDate,
  "status" : "$inputRoot.status",
  "stopDate" : $inputRoot.stopDate
}

In the response, output will be in JSON and not stringifyed. Alternatively, you can have a look at $util.parseJson

If you, or anyone, want to use it with CDK, pay attention to the ResponseModels. The response model for your statusCode have to be coherent with the template.

exemple 1: for statusCode 200, response model is Model.EMPTY_MODEL so responseTemplate have to be "" (empty string)

exemple 2: for statusCode 200, response model is myModel so responseTemplate cannot be "" (empty string)

Here is the same template but declared in CDK TS:

responseTemplates: {
    "application/json": "#set($inputRoot = $input.path(\"$\")) { \"name\": \"$inputRoot.name\", \"output\" : $inputRoot.output, \"startDate\" : $inputRoot.startDate, \"status\" : \"$inputRoot.status\", \"stopDate\" : $inputRoot.stopDate}"
}

Useful information can be found here in aws doc:

https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-data-transformations.html

Also Cloud Guru have made a video on this subject:

https://www.youtube.com/watch?v=4DGhYtR2S2k&ab_channel=CloudGuru

Upvotes: 1

Related Questions