AWS diaries: serving HTML from lambda

AWS lambda is a neat feature that runs code in response to requests and transforms the code’s output into some response. Requests can be an event occurring in the AWS platform such as an S3 modification or an HTTP request. The response is an MVC-style model which needs to pass through some network component, like the API gateway in order to reach a browser; by default, the API gateway renders lambda responses into JSON. If you need anything else than JSON (eg. HTML), then things become tricky.

I wrote “tricky” because the API gateway definition language is Swagger which, while a fairly common DSL, is not an AWS native format and issues are hard to track.

Searching for “aws lambda render html” returns https://kennbrodhagen.net/2016/01/31/how-to-return-html-from-aws-api-gateway-lambda/ which succinctly describes the AWS gateway method response mapping configuration between the text/html content type and $input.path('$')… (don’t ask me how Ken came up with that). It does the trick, but most of us work with cloudformation templates which mix Swagger DSL and cloudformation DSL – at this point I had no idea how to code the mapping into yaml.

The next search “export aws API gateway” yields this little gem:

aws apigateway get-export --parameters extensions='apigateway' --rest-api-id abc12345 --stage-name dev --export-type yaml mapping.json

where “abc12345” is the API gateway ID (look it up in the AWS web management UI) and “dev” is the stage name. This command returns the API gateway’s mapping as a Swagger document!

The AWS cloudformation yaml syntax follows closely the Swagger notation, so the final entry in the cloudformation template becomes:

x-amazon-apigateway-integration:
  httpMethod: POST
  type: aws
  uri:
     Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaUI.Arn}/invocations
  responses:
     default:
       statusCode: "200"
       responseParameters:
         method.response.header.Access-Control-Allow-Origin: "'*'"
         method.response.header.Content-Type: "'text/html'"
       responseTemplates:
         'text/html': "$input.path('$')"

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.