8

I need to include the request time in the body mapping template for an API Gateway method. Is there a date/time variable or function? I couldn't find anything in the template reference.

Example body mapping template:

Action=SendMessage&MessageBody=$util.urlEncode("{""timestamp"":""TIMESTAMP_HERE"",""body-json"":$input.json('$'),""params"":""$input.params()""}")
John Himmelman
  • 21,504
  • 22
  • 65
  • 80

3 Answers3

12

UPDATE: API Gateway just added two new context variables http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html

$context.requestTime    The CLF-formatted request time (dd/MMM/yyyy:HH:mm:ss +-hhmm).
$context.requestTimeEpoch   The Epoch-formatted request time.

API gateway doesn't support this currently. Its been requested before on the forums - https://forums.aws.amazon.com/thread.jspa?messageID=697658&. We have this feature in our backlog, but unfortunately I can't commit to any timelines.

Abhigna Nagaraja
  • 1,874
  • 15
  • 17
  • Thanks for the update! We have the method integration request mapped to SQS - for a workaround we're using the First Received timestamp from SQS. – John Himmelman Dec 22 '16 at 00:03
  • This would be a very useful feature, if you could provide something like an environment variable to get the timestamp. – Siddardha Nov 21 '17 at 17:45
  • 1
    Was anyone successful using $context.requestTime? I'm still getting an empty string when using it in our API gateway integration. – giorgioca Nov 28 '17 at 15:45
  • 1
    @giorgioca $context.requestTimeEpoch and $context.requestTime are only available once the API has been deployed. You can test this by creating a Get Method set to 'Mock' and changing the Body Mappings Template in Integration Response to something like: `{ "api_id" : "$context.apiId", "epoch": "$context.requestTimeEpoch", "requestTime": "$context.requestTime" }` . Deploy, visit the URL. Should have your time. – CZauX Feb 20 '18 at 20:52
  • $context.requestTimeEpoch is returned in Milliseconds for those looking for that precision. – CZauX Feb 20 '18 at 20:54
  • Is there a way to get the `messageID` that is given as a response to the user invoking the API? See my question at https://stackoverflow.com/questions/51105990/cant-get-api-gateway-requestid-in-lambda-function/51125484#51125484 – wprins Jul 01 '18 at 21:27
5

There appears to be a way to get a timestamp from the API Gateway request, but you need to look in the X-Ray documentation to find it:

Amazon API Gateway gateways add a trace ID to incoming HTTP requests in a header named X-Amzn-Trace-Id.

(...)

A trace_id consists of three numbers separated by hyphens. For example, 1-58406520-a006649127e371903a2de979. This includes:

  • The version number, that is, 1.
  • The time of the original request, in Unix epoch time, in 8 hexadecimal digits. For example, 10:00AM December 2nd, 2016 PST in epoch time is 1480615200 seconds, or 58406520 in hexadecimal.

(...)

Community
  • 1
  • 1
Free Willaert
  • 1,139
  • 4
  • 12
  • 24
  • Does anyone know if "The time of the original request" is the time the browser claims to have started the connection? Or is it the time when AWS infrastructure first sees the connection? In other words, **can this be used to measure network latency from client to AWS?** – Neo Aug 05 '17 at 02:00
  • You can access the header with the following code: `$input.params('X-Amzn-Trace-Id')` – dtbarne Oct 13 '17 at 17:15
  • @dtbarne - Doesn't seem to work. I get an empty string when I try to use it. – Jón Trausti Arason Oct 18 '17 at 15:16
  • Anyone figure this out? – tmanion Oct 25 '17 at 17:44
  • @raRaRa check the rest of your implementation. This definitely works...we're using it in multiple production APIs now. – dtbarne Nov 03 '17 at 00:22
  • Is there a way to access this in **Path override** using something similar to `method.request.path.var_name`? I tried `method.request.header.X-Amzn-Trace-Id` but it didn't work. – Siddardha Nov 21 '17 at 17:49
0

Just set a time value at the top of your template for the date you want it to expire. Then add that as an attribute to your Item. For example, if you want the Item to expire in 60 days, you would add 5184000 seconds.

#set($expireDate = $context.requestTimeEpoch + 5184000) 
{
  "TableName": "your-table-name",
  "Item": {
      ... other attributes
      "expireDate": {"N": "$expireDate"},
  }
}
MattC
  • 5,874
  • 1
  • 47
  • 40
  • 2
    This looks like you're using DynamoDB TTL, maybe? Just an FYI that DynamoDB uses the epoch time in _seconds_ and this is _milliseconds_, so it might take longer to expire than expected :D – Aidan Steele Nov 23 '21 at 00:42