Home > other >  Inject dynamic (server side) variables into integration request path in API Gateway
Inject dynamic (server side) variables into integration request path in API Gateway

Time:11-09

I have an AWS API Gateway and I want to have a single POST endpoint to which clients could post JSON data. I want to take that payload and create an S3 object in a bucket that contains the payload that the client posted.

I have been able to do all of this to a hard coded object key but now I'm trying to figure out a way to always generate a new object for each new request. However, I'm not finding any way to inject something like a date or a UUID into the integration request "URL Path Parameters" (which is the thing that dictates the object key that I will be writing).

Preferrably I would like the object key to be something like yyyy/MM/dd/hh_mm_ss_sss-<short uuid>.json to make sure that if two requests are received at exactly the same millisecond, they'd have a very very small chance of the latter one overwriting the former.

But as I said, I am not finding any way to do this in my URL Path Parameters mapping. The only thing I seem to be able to do there is use data from the incoming API call request (path, querystring, header, multivaluequerystring, multivalueheader) to fill this in and I don't want to use that as I don't want the caller to be able to manipulate what the object key value will be.

So, is there no way to do this? Is my only option then to send the payload to a lambda and have the lambda write the payload to S3 with the object key that I want?

CodePudding user response:

I believe this is what you are looking for: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html

Specifically, look at the $context Variables, those can be used in the URL Path parameters on the Integration Request without the '$' prefix.

Step 1: Set up your the Path Override parameter on the Integration Request to be something like this:

[your_s3_bucket_here]/{time}_{rid}.json

Step 2: Set up the following URL Path Parameters on the Integration Request to match:

[NAME] : [MAPPED FROM]
time   : context.requestTimeEpoch
rid    : context.requestId

This will result in a file name like this: 1667905369424_63246784-f5cf-4113-8ee0-2146c3b50f51.json which should have little chance of naming conflict. You could probably get away with only using the requestId and not even bother with also adding request time to the name.

If you want a more human-readable format, you could use the context.requestTime (instead of requestTimeEpoch) variable and use the mapping template context.requestOverride.path.time to modify the formatting to something more appropriate for a filename.

  • Related