2019-06-04 20:34

Capturing AWS API Gateway Requests as SQS Messages

At the end of this article you know how to create and store a payload as shown below in Amazon Simple Queue Service based on an inbound AWS API Gateway request:

{
  "bodyJson": {
    "foo": "bar",
    "woo": 3
  },
  "bodyRaw": "{foo:\"bar\",woo:3}",
  "requestId": "334029f8-***-ad7a6e7bbd88",
  "resourcePath": "/v1/enqueue",
  "apiId": "7cy***abd",
  "stage": "Staging",
  "resourceId": "4l***dd",
  "path": "/Staging/v1/enqueue",
  "protocol": "HTTP/1.1",
  "requestTimeEpoch": "1559294802021",
  "params": {
    "path": {
    },
    "querystring": {
      "foo": "bar"
    },
    "header": {
      "Accept": "*/*",
      "Content-Type": "application/json",
      "Host": "***.execute-api.eu-west-1.amazonaws.com",
      "User-Agent": "insomnia/6.5.3",
      "X-Amzn-Trace-Id": "Root=1-5cf0***719e",
      "X-Forwarded-For": "188.***.***.***",
      "X-Forwarded-Port": "443",
      "X-Forwarded-Proto": "https"
    }
  }
}

You can use this data for logging, debugging, or perhaps for a basic analytics application.

While investigating this topic I found the following resources helpful:

Create SQS Queue

In this step we're creating an SQS queue.

  • Open https://console.aws.amazon.com/sqs/home

  • Click "Create New Queue".

  • Enter a name for your queue e.g. test-sqs-queue.

  • Select "Standard Queue" (the FIFO-type queue requires passing along additional IDs which is beyond the scope of this article).

  • Click "Quick-Create Queue".

  • Select the queue and copy/paste the URL and ARN values displayed in the bottom pane to a notepad because you'll need these values later on. The values look like this:

URL: https://sqs.eu-west-1.amazonaws.com/744520962556/test-sqs-queue

ARN: arn:aws:sqs:eu-west-1:744520962556:test-sqs-queue

Create IAM Policy

In this step we're creating an IAM policy.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sqs:SendMessage",
      "Resource": "REPLACE-WITH-YOUR-SQS-ARN"
    }
  ]
}
  • Click "Review policy".

  • Enter a name for your policy in the next screen e.g. test-sqs-policy.

  • Click "Create policy".

Create IAM Role

In this step we're creating an IAM role.

  • Open https://console.aws.amazon.com/iam/home#/roles.

  • Click "Create Role".

  • Select "AWS service" and choose "API Gateway".

  • Click "Next: Permissions".

  • Don't make any changes in the next screen, just click "Next: Tags".

  • Again don't make any changes in the tags screen, just click "Next: Review".

  • Enter a name for the new role e.g. test-sqs-role.

  • Click "Create role". You should see a notification saying something like "The role test-sqs-role has been created.".

  • Select the new role and click "Attach policies".

  • Use the search filter to find test-sqs-policy. Tick the checkbox next to the policy and click "Attach policy". You should see a notification saying something like "Policy test-sqs-policy has been attached for the test-sqs-role.".

  • Copy/paste the Role ARN to a notepad because you'll need it later on. The ARN looks like this: arn:aws:iam::744520962556:role/test-sqs-role.

Create API Gateway

In this step we're creating an API Gateway.

  • Open https://console.aws.amazon.com/apigateway/home#/apis.

  • Click "Create API"

  • Select "REST", then "New API", and choose a name e.g. "Test API Gateway".

  • Click "Create API".

  • Click "Actions" and choose "Create Resource".

  • Enter a resource name e.g. v1. Click "Create Resource".

  • Click /v1, select "Actions", choose "Create Resource", and create a resource called traces. The resources path now looks like /v1/traces.

  • Click traces, select "Actions", choose "Create Method", select POST, and click the round checkbox icon.

  • Now select "AWS Service" at the right side of the screen. Select the appropriate region and choose "Simple Queue Service (SQS)" from the "AWS Service" select.

  • Select "Action Type" / "Use path override".

  • Look up the URL created in step "Create SQS Queue" and enter only the path part of this URL in the "Path override (optional)" field. In our example the path override should be set to 744520962556/test-sqs-queue.

  • Look up the Role ARN you created in step "Create IAM Role" and paste the value in the "Execution role" field.

  • Click "Save".

  • In the next screen, click "Integration Request".

  • Add an HTTP Header. Set "Name" to Content-Type and "Mapped from" to 'application/x-www-form-urlencoded' (notice the single quotes, they are required for static values!).

  • Add a Mapping Template. Select "Never" and add a Content-Type application/json.

  • Add the following template:

Action=SendMessage&MessageBody={
  "bodyJson": $input.json('$'),
  "bodyRaw": "$util.escapeJavaScript($input.body)",
  "requestId": "$context.requestId",
  "resourcePath": "$context.resourcePath",
  "apiId": "$context.apiId",
  "stage": "$context.stage",
  "resourceId": "$context.resourceId",
  "path": "$context.path",
  "protocol": "$context.protocol",
  "requestTimeEpoch": "$context.requestTimeEpoch",
  #set($allParams = $input.params())
  "params" : {
    #foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
    "$type" : {
      #foreach($paramName in $params.keySet())
      "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
      #if($foreach.hasNext),#end
      #end
    }
    #if($foreach.hasNext),#end
    #end
  }
}

Deploy API

  • Select "Actions" at the top of the screen and choose "Deploy API". You may have to create a stage first e.g. staging.

  • In the next screen you'll see the new endpoint e.g. https://scn6oc2fnj.execute-api.eu-west-1.amazonaws.com/staging.

  • Use curl to send a test request to your new API end point. Important: make sure you use the complete path e.g. https://scn6oc2fnj.execute-api.eu-west-1.amazonaws.com/staging/v1/traces in our case.

  • Open https://console.aws.amazon.com/sqs/home and tick the checkbox next to the queue name.

  • Click "Queue Actions" and select "View/Delete Messages". Click "Start Polling for Messages". You should see a new message containing the request payload you just sent!

§ Permalink

ξ Comments? Kudos? Find me on Twitter

.