How to configure $default path in AWS API gateway? - amazon-web-services

We are trying to leverage the $default path in AWS API gateway as per https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-routes.html
configured api gateway like this leveraging the $default as one of the routes
/
/-default
ANY
/api
/{proxy=}
when we are trying to invoke the api gateway on the $default path and GET call
https://apigateway.amazonaws.com/prod/test
we assumed it will invoke the default path but it didn't
message: "Missing Authentication Token"
but when we do
https://apigateway.amazonaws.com/prod/api/test
the api integration is invoked
Note : we already tried configuring greedy path{proxy+} instead of $default that does not work as the greedy path always takes precedence and /api routes also get routed to greedy path
Any help from the community in pointing us in the right direction would be of great help

It seems like you have not set up your API Gateway HTTP API routes correctly causing the routing to not work as expected. Would also like to mention that HTTP APIs and REST APIs are different types of API Gateway APIs, so do confirm that you have configured your API correctly.
Coming to how the routing would work, as a sample, here's how the routes for the API look:
Request to GET https://xxxx.execute-api.xxxx.amazonaws.com/prod/test : Routed to $default path
Request to GET https://xxxx.execute-api.xxxx.amazonaws.com/prod/api/test : Routed to /api/{proxy+} path
Further, if you have a greedy path at ANY /{proxy+}, then as you mentioned, this greedy path will take priority over the $default route. However, this would not take precedence over the ANY /api route if the request matches to the route, for example: GET https://xxxx.execute-api.xxxx.amazonaws.com/prod/api : would be routed to /api path and not /{proxy+}
The routing priority is also explained here
After selecting a stage, API Gateway selects a route. API Gateway selects the route with the most-specific match, using the following priorities:
Full match for a route and method.
Match for a route and method with a greedy path variable ({proxy+}).
The $default route.
If no routes match a request, API Gateway returns {"message":"Not Found"} to the client.
EDIT:
To create the $default route, just specify the path as $default when creating the route

Related

AWS API Gateway custom domain name results in {"message":"Not Found"}

I tried to create a HTTP API through API Gateway.
This API generated a URL e.g. https://{api-id}.execute-api.{region}.amazonaws.com/
This endpoint works as intended.
After this; I created a custom domain name and under "Api Mappings", I added this newly created API, set the stage the $default and left Path (Optional) as blank. This generated another endpoint (which is supposed to be added as an A record in Route53). When I try to hit this new endpoint; I get {"message":"Not Found"}. This "connection" between the custom domain endpoint and the working api gateway endpoint doesn't seem to work. Any pointers on how to fix this?
Other Information:
I own the custom domain
Adding a custom domain required uploading a SSL certificate (I had a valid one and I uploaded it - verified and all good)
The API is a basic HTTP API which refers to a Cloudfront URL. This endpoint is fully functional and working as expected.
Endpoint Type: Regional
No multiple "Stages" for API/Routes - only a $default one

How to have path based routing for AWS Application Load Balancer

I have deployed 2 services in ECS Web and API, Both of the services have their ALB, How can I configure my domain as follows:
example.com -> Web ALB
example.com/api -> API ALB
I tried creating a single ALB for both web and api target group and added a path based routing in rules but /api request is received by nodejs with full path, Eg. if a call example.com/api/products node is getting /api/products instead of /products
What could be a proper way of implementing this?
Thanks!
call example.com/api/products node is getting /api/products instead of /products
That's correct and that's how it should work. In other words, ALB can't change path from /api/products to /products, because ALB only forwards requests, it does not re-write them.
You can have a look at CloudFront, which could be helpful in that case.

AWS API Gateway path based routing to private integrations

I am using AWS HTTP API Gateway to route requests to my integrations in the VPC.
I've added a custom domain and I want to route my requests to my integrations based on the paths in the following manner
Basically all the requests coming to the API gateway should be routed to different integrations based on the base paths but the integration should receive only the path after the base path. So all the requests coming to my.custom.domain/foo/<path1>/<path2>/<path3> should be routed to the integration Foo but the gateway should strip the base path i.e. /foo and forward the rest to the integration.
The functionality is same as below in nginx where nginx strips the foo from the request path and forwards the rest to the service
location /foo/ {
proxy_pass http://foo.service
}
I've tried adding custom domain and API mapping in the AWS API gateway but that doesn't work. My service still receives the whole path from the request and hence fails.
I am unable to find any documentation or mentions on the internet about this.
You can use routes and parameter mappings to achieve this.
Create 2 routes with 2 path mappings:
path: "/foo/{proxy+}" with parameter mapping: "/$request.path.proxy"
path: "/bar/{proxy+}" with parameter mapping: "/$request.path.proxy"
"proxy+" is a greedy path variable, so it will contain the path after /foo/ or /bar/.
You can use this variable with a parameter mapping to overwrite the path the backend will receive.
This is how it looks like in AWS CDK
const privateIntegration = new HttpServiceDiscoveryIntegration('test', service, {
parameterMapping: new ParameterMapping()
.overwritePath(MappingValue.custom('/$request.path.proxy'))
})

Can I get an example of how to connect a lambda function to a domain name?

I've been wasting about 12 hours going in circles in what seems like this:
I am trying to just make a simple static landing page in lambda and hook the root of a domain to it.
The landing page works, but api gateway didn't because AWS doesn't seem to set permissions properly by default ("internal server error" with API gateway and lambda on AWS) but now the gateway link works.
So the next steps were the following:
add a custom domain name in the api gateway
add the api mapping in the custom domain name
in route 53, create a wildcard certificate with *.domain.com and domain.com
create an A record that points to the api gateway with domain.com
create a CNAME record that points to the A record
and I get an error 403 with absolutely nothing in the log. I log both 'default' and '$default' stages in the api gateway.
I read https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-403-error-lambda-authorizer/ which is all about looking at what's in the logs...
and I find the doc is both everywhere and nowhere because it's built as chunks of 'do this' and 'do that' without ever painting a whole picture of how each piece is connected to the other, or any graph with the hierarchy of services, etc. Reminds me of code that works only when you follow the example documented and breaks otherwise.
I'm sure I'm doing something wrong, but given the lack of logs and lack of cohesive documentation, I have no idea about the problem.
Not to mention that http doesn't even connect, just https.
Can anyone outline the steps needed to achieve this? essentially: [http|https]://(www).domain.com -> one lambda function
You cannot use API Gateway for an HTTP request; it only supports HTTPS.
From the Amazon API Gateway FAQs (emphasis mine):
Q: Can I create HTTPS endpoints?
Yes, all of the APIs created with Amazon API Gateway expose HTTPS endpoints only. Amazon API Gateway does not support unencrypted (HTTP) endpoints. By default, Amazon API Gateway assigns an internal domain to the API that automatically uses the Amazon API Gateway certificate. When configuring your APIs to run under a custom domain name, you can provide your own certificate for the domain.
You can use CloudFront to automatically redirect HTTP to HTTPS. How do I set up API Gateway with my own CloudFront distribution? provides a pretty simple walkthrough of connecting an API Gateway to CloudFront (you can skip the API Gateway portion and use the one you created). The important thing you'll need to do that is not in that document is to select Redirect HTTP to HTTPS.
If you truly need HTTP traffic you're probably going to need to go with an ALB.

Default path in AWS API gateway?

We have an Rest API config in AWS API gateway where we want to route to handle a default path
/
/api
/$default (default path here)
Note we are not looking for the greedy path {proxy+}
/
/api
/{proxy+}
the problem with the greedy path is no request will route to /api ...always the {proxy+}
will take precedence even though the request has /api (tried it out)
Any help from the community in pointing us in the right direction would be of great help.
You can use the $default route to catche requests that don't explicitly match other routes in your API.
When the $default route receives a request, API Gateway sends the full request path to the integration. For example, you can create an API with only a $default route and integrate it on the ANY method with the https://petstore-demo-endpoint.execute-api.com HTTP endpoint.
When you send a request to https://api-id.execute-api.us-east-2.amazonaws.com/store/checkout, API Gateway sends a request to https://petstore-demo-endpoint.execute-api.com/store/checkout.
You can read more about it here.