Versioning using base path mappings in AWS API Gateway - amazon-web-services

I have a pretty straightforward stack: API Gateway sitting in front of a lambda. Currently my paths looks something like:
/dogs, /dogs/{id}, etc.
All I want to do is add a version to the base path (i.e. api.dogs.com/v1/dogs). I tried doing this by creating a custom domain name with a base path mapping of v1 pointing to my stage in API Gateway.
This routes just fine through API Gateway but has issues once it hits the routing logic in my lambda. My lambda is expecting /dogs but with the base path mapping the path is actually v1/dogs.
What's a good way to approach this? I want to get away from having to deal with versions directly in my code (lambda) if possible.

In the event object your lambda function receives you should actually find all the needed information with and without versioning:
event = {
"resource": "/hi",
"path": "/v1/hi",
"requestContext": {
"resourcePath": "/hi",
"path": "/v1/hi",
....
},
....
}
Just adjust the code in your router logic to access the desired attributes should fix your problem and remove the need to care about versioning again in your code.

Related

How do I add binary media types to an existing API Gateway that I've imported into a CDK stack?

I have an AWS CDK stack in which I'm referencing an existing API Gateway like this:
api = apigateway.RestApi.from_rest_api_attributes(self, "API",
rest_api_id="api-id", root_resource_id="root-resource-id")
After I have the reference, I want to configure the allowed binary media types to be "application/pdf" and "image/*". The problem is that I can't find a method where I can set these. The only place I've found where you can set the binary media types is in the constructor for the RestApi class and I can't use that because the API has already been created.
There is a binary_media_types property on the RestApi class, but that had no effect when I tried setting its value:
api.binary_media_types = ["application/pdf", "image/*"]
Does anyone know another way to change the binary media types in this situation by using the CDK library?

Make AWS IoT rule trigger Lambda function using specific alias

I'm making updates to a Lambda function that is triggered by an AWS IoT rule. In order to be able to quickly revert, use weighted aliases, etc., I would like to update this rule to point to a specific production alias of the function so that I can make updates to $LATEST and test them out. If everything goes well, I would make a new version and make the production alias point to that.
But when I try to update the action to trigger the alias instead of $LATEST, I'm only given choices of versions or $LATEST:
Any ideas? Google yields nothing.
I had to add the trigger on the other side. I had to add the trigger to the production alias and then delete the link to default/$LATEST under the Lambda function itself.
As far aas I know:
You can define an alias via the CLI. It is not possible via the web interface I think.
Have a look here.
{
"topicRulePayload": {
"sql": "SELECT * FROM 'some/topic'",
"ruleDisabled": false,
"awsIotSqlVersion": "2016-03-23",
"actions": [
{
"lambda": {
"functionArn": "arn:aws:lambda:us-east-1:123456789012:function:${topic()}"
}
}
]
}
}
You can type: "functionArn": "arn:aws:lambda:us-east-1:123456789012:function:${topic():MY_ALIAS}"
But you have to set this up via the CLI.

How to retrieve a Lambda function's associated API Gateway methods with boto3

I'm trying to write a Python script that lets you rename a Lambda function by copying all of the code and configuration to a new function. As part of that process, I want to take all of the API Gateway methods that point to the old function and redirect them to point to the new function.
Is there a way to accomplish this with boto3?
Yes, it is doable, but you have to have two clients for APIGateway.
Following the calls you can make for doing this:
get_apis > gives all the APIs deployed, then further you can drill down to individual APIs using get_api
get_resources > This gives you all the paths in the chosen rest API.
get_integration > Gives you something like below:
{
"type": "AWS_PROXY",
"httpMethod": "POST",
"uri": "arn:aws:apigateway:us-east1-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:1234567890:function:myfunction/invocations",
"credentials": "arn:aws:iam::1234567890:role/myrole",
...
}

Multiple API Gateway instances, one lambda function

I am trying to build a system where multiple APIs gateway instances should execute the same lambda function.
My problem is that I would like to change only the lambda configuration in function of the API gateway used.
Let's take the name of a database as an example that should change if the lambda is being triggered from one API or the other.
Example:
API Gateways:
https://my-first-api-gateway.execute-api.eu-west-1.amazonaws.com
https://my-second-api-gateway.execute-api.eu-west-1.amazonaws.com
I then have one lambda function being called by the two APIs: say_hello.
This function has to retrieve a quote from a database. If the function has been called from my-first-api-gateway the lambda function has to use my_first_database and if the function has been called from my-second-api-gateway, it has to use my_second_database.
The only solution I came with is to deploy as many lambda functions as I have API Gateways. And then use environment variables to store my database name.
I don't like my solution because when I update a single line of code I'll have to redeploy all of my lambda functions.. (if I have 300 different databases to use, that would mean to update 300 lambda functions at once..)
Thank you for your ideas on this subject!
If you use a Lambda-Proxy integration you should be fine.
Full details of the event can be found here, however critically the headers Host, origin and Referer all point the the API Gateway uri:
"headers": {
"Host": "j3ap25j034.execute-api.eu-west-2.amazonaws.com",
"origin": "https://j3ap25j034.execute-api.eu-west-2.amazonaws.com",
"Referer": "https://j3ap25j034.execute-api.eu-west-2.amazonaws.com/dev/"
}
Therefore it should be fairly trivial for you to branch/look-up your database behaviour from this information.

How to setup AWS API gateway resource to take matrix parameters?

I have been trying to setup a resource using AWS API Gateway but I can't seem to find a way to either set or access matrix parameters.
I want to be able to set up a resource similar to the following -
GET /image;height=750;width=1000;format=png
Is it possible ?
You need to configure the setup to use Query Parameters.
You do this in the Method Request area of a method configuration from within the console:
https://console.aws.amazon.com/apigateway/home?region=<region-id>#/restapis/<api-id>/resources/<resource-id>/methods/<method-type>
You can also do this use the AWS API Gateway HTTP API putMethod endpoint, or the AWS#APIGateway#putMethod call in any of their SDKs.
API Gateway currently does not support matrix parameters. As a workaround, you could use query parameters as already mentioned and parse them in your backend.
Best,
Jurgen
I realize that this is a very old question. Leaving my response in case someone has a similar challenge
There are multiple ways to set this up. It all comes down to the context in which the API is intended to be used.
While query parameters will solve the problem, they are not the best suited for representing a resource. They fit well with scenarios that involve filtering. If this API is intended to be used as a source for <img /> tags on the UI, this pattern GET .../images/{widthxheight}/{imageName}.{extension} can be used.
Ex: GET .../images/200x400/sponge-bob.png
However, if the intent is for this API to be used for the purpose of looking up. the below definition can be used -
POST .../image-results
Content-Type: application/json
{
"name":"sponge bob",
"height": 400,
"width": 200,
"format": "png"
}