AWS Api gateway custom domain routing to wrong base url - amazon-web-services

I'm developing an Angular Universal serverless app in AWS Lambda/Api gateway. The app works perfectly using the standard api url ( {api-id}.execute-api.{region}.amazonaws.com/{stage}/) but now I'm trying to deploy it in a human-readable url using Api Gateway's Custom domain names.
For that I followed the docs and troubleshooted using other stackoverflow's questions, but now I'm faced with a problem and can't find another question that looks like my problem.
I have already setup the API, the custom domain name (which created a cloudfront distribution) and a Route53 A-type ALIAS routing to this new cloudfront distribution and the routing kind of works.
The problem I'm facing is that when I'm using the new domain name, the angular app cant find assets like CSS, Icons,etc. All of them works fine using the standard api url but not with the custom.
To do some debugging I configured Api Gateway to log requests to CloudWatch, and I can see that when I'm using the standard url, the resource path log is like this:
HTTP Method: GET, Resource Path: /main.4d57a71fd195330e8ee9.js
But when I use the custom URL the same log is like this:
HTTP Method: GET, Resource Path: /development/main.4d57a71fd195330e8ee9.js
I'm guessing it has something to do with the base URL in the custom domain name configuration of Api Gateway, I tried changing it to everything I could think of but nothing fixed it.
Here is a screenshot of my Api Gateway configuration.
Api gateway - Custom Domain Names configuration
Tell me if you need anything more and sorry if bad english.
Thanks in advance.
EDIT: I should make clear that I'm trying to point to the "development" stage of my api

I believe you simply need to reconfigure your custom domain. It should be sufficient for you to change the following;
In "Base Path Mappings" section change Path from "/development" to just "/"

I had similar problem. The only workaround for me is to set baseHref to "/" in environment.serverless.ts and have one single mapping in custom domain name from "/" to "{YOUR-API}:production".
This breaks direct url access to the API but access via custom domain name works fine.

Related

AWS Route 53 Domain Point To Github Pages

I am new to working with AWS and route 53 so any help is appreciated.
I have created an organization on GitHub, and then created a simple repository for a static site to display with Github pages. this is working as expected and I can see the static site at the URL generated by Github (something like: https://<githubOrgName>.github.io/<repoName>/)
I got a domain from AWS and now I'm trying to set it up so the apex domain (e.g. "my-domain.com") points to the Github pages site.
I followed the instructions found at: https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/about-custom-domains-and-github-pages ... but it doesn't seem to be working.
I am trying to make it so that the apex domain points to the repository Github page. something like:
https://my-domain.com -> https://<githubOrgName>.github.io/<repoName>/
... but this only shows a blank screen when I go to the root domain ("my-domain.com"). I have also tried to go to https://my-domain.com/<repoName>/... but this shows me a Github 404 page (so it seems to be correctly forwarding something to Github):
my AWS route 53 configuration is similar to the following (i have tried to remove sensitive details):
can anyone explain to me what I am doing wrong? I am new to working with domains so any help is appreciated.
Using Route53 alone won't help you there, because your target URL contains a URL path i.e. /<repoName>/.
DNS is a name resolution system and knows nothing about HTTP
Furthermore, the origin server (github.io) might be running a reverse proxy which might be parsing the request headers, among which is the Host header. You browser automatically sets this header to the url you feed it. Eventually, you send it the wrong header (i.e. https://my-domain.com/), which Github cannot process. You can explicitly set this header (e.g. via curl) to what Github is expecting, but I believe it's not what you and your users would like.
Instead, you could try using layer 7 redirects (301/302) with the help of Lambda#Edge (provided by AWS CloudFront). I have created a simple solution using the Serverless framework, which does the following redirects:
https://maslick.tech -> https://github.com/maslick
https://maslick.tech/cv -> https://www.linkedin.com/in/maslick/
https://maslick.tech/qa -> https://stackoverflow.com/users/2996867/maslick
https://maslick.tech/ig -> https://www.instagram.com/maslick/
But you can customize it by adjusting handler.js according to your needs. You might also need to create a free TLS certificate using AWS Certificate Manager in the us-east-1 region and attach it to your CloudFront distribution. But this is optional.
Lambda#Edge will give low latencies, since your redirects will be served from CloudFront's edge locations across the globe.
How I got it to work was:
Set a CNAME record from example.org to <USERNAME>/github.io. in the Route 53 console
Set Custom domain to example.org in the Github Pages settings for github.com/<USERNAME>/<REPO>
Note: You shouldn't be setting the CNAME record to <USERNAME>/github.io/<REPO>
Source: https://deanattali.com/blog/multiple-github-pages-domains/

why does api gateway with http api using api mapping fail with 404?

I have a custom domain name in AWS API gateway. I am using the same domain for 2 separate API stages. One API stage is REST API, and the other HTTP API.
When I test out my setup, everything works for the REST API. However, the mapping path for HTTP API is not working and I get status-code = 404 Not Found, with 0kb body.
references used:
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-mappings.html
https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-mappings.html
From my testing in postman, i get the following result when calling the custom domain.
1. {{api.gateway.custom.domain.url}}/foobar - works
2. {{api.gateway.custom.domain.url}}/this-no-work/foobar - 404
3. {{api.gateway.custom.domain.url}}/this-works/foobar - works
does anyone know why (2) gives 404? api-gateway REST API with mapping works while api-gateway HTTP API will return 404 with 0kb body. Is there something I am missing?
note: the (none) path mapping has been added for a sanity check, and I was able to get the expected response.
I had the same problem.
The problem is in the configuration of routers of your application.
When you configure one API mapping in AWS API Gateway, the configured path (this-no-work) is passed to your web application as a prefix of routes.
SO ... if you have one route like this:
/api/foobar
you need configure one more route with the prefix point to the same action:
/this-no-work/api/foobar
A good one is to make one global configuration to your web app.
You can note it enabling the cloudwatch logs of your API Gateway stage and looking into the cloudwatch logs the path property passed from API Gateway to the Web application.
Thanks to answer from #gean-ribeiro, I was able to figure why my HTTP API was returning 404 Not Found.
Turns out it was not an issue with HTTP API. The error 404 Not Found with 0kb body was coming from the API integration sitting behind APIG. Specifically, it was a load balancer using rules based on HTTP path pattern.
By default, any unmatched path pattern will return 404 with text/plain body. this-no-work was a new HTTP API I added, and it did not have the necessary listener rules.
Once I added a new listener rule for HTTP Path pattern is /this-no-work/*, it worked as expected..
when default endpoin is created in my case it uses this pattern
https://{api_id}.execute-api.{region}.amazonaws.com/
an answer might be: Disable the default endpoint for an HTTP API
more details here
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-disable-default-endpoint.html

API Gateway URI Versioning

I keep seeing comments on how to do URI versioning in API Gateway, and these all say the same thing,
Do not create the version path (/v1) as a resource in your API. Instead, simply call you API "Names V1" and start creating the resources (/names). When you want to make a breaking change and create a new version of the API, we recommend you create an entirely new API called "Names V2". Once again, simply create your resources without the version path.
To bring the two APIs together, you can use custom domain names. A custom domain name in API Gateway includes both a fully qualified domain name and a base path. Create two custom domain names:
myapi.com/v1 -> points to the prod stage of the Names V1 API
myapi.com/v2 -> points to the prod stage of the Names V2 API
However, when you try to create a Custom Domain Name with a "/" in it, API Gateway responds with "Invalid Domain Name". So if you try to do it on the mapping, you get something similar mentioning the special characters you can use, and "/" is not one of them. So your only option is to use the Stage variables which these posts mention the challenges of doing it that way.
Additionally, if you just make it "v1" with no slash, then we are unable to have a custom domain like "api.whatever.com". Then makes the custom domain be specific to an API area that needs to be versioned. Ex. "stores.whatever.com". This causes each API to have their own subdomain.
URI-based Versioning for AWS API Gateway
API Versioning with AWS API Gateway
Sorry for asking a new question, but I'm not allowed to add a comment on the posts.
I'm not sure I understand the request here, let me try to clarify. When a request comes in to your custom domain name api.whatever.com, API Gateway needs to determine where to send the request. API Gateway will look at the path and then determine if there are any API:STAGE mappings for that path. You can configure an empty base path mapping on a custom domain name, but then all requests without a path to that custom domain name will be routed to the API:STAGE mapping. It seems like you're trying to route requests to either api.whatever.com or stores.whatever.com, you can do this with two custom domain names each with their own empty base path mapping. For example:
Custom domain name1: api.whatever.com
api-id: 12345
stage: Live
api-mapping-key: NULL
Custom domain name2: stores.whatever.com
api-id: 67890
stage: Beta
api-mapping-key: NULL
Your clients will have to specify the proper domain name when calling your APIs.

API Gateway Proxy Without URL Redirection

I’m using AWS API Gateway at https://console.aws.amazon.com/apigateway/home
I did all of the steps to set up a proxy for http://foo.com (example)
I deployed it and the URL is http://bar.com (example)
When I go to http://bar.com/hello, it redirects me to http://foo.com/hello
I want it to stay at http://bar.com/hello, but deliver the contents from http://foo.com/hello like a normal proxy service
Note: My primary intent is to get around CORS issues with a service
It seems to me that whatever service you're using is forcing the redirect like #Steve's comment mentioned. They might be forcing HTTP_REFERER to be a certain domain.
Since I don't know what service you're calling this is just a guess.

AWS Api Gateway + Lambda + custom domain (Route53) Missing Authentication Token issue

I am aware that many similar questions have been posted and answered here but none of them is quite the same with what I am experiencing.
I have a Lambda function that handles incoming requests (GET and POST). I also set up an api gateway as public facing endpoint. Additionally, I set up custom domain following Set up Custom Domain Name for API Host Name
The testing call works in both of lambda and api gateway console. Everything also works using the invoke URL but not with the custom domain I've set up.
Here are some more details:
Invoke URL (Works) :
https://{api gateway id}.execute-api.us-west-2.amazonaws.com/prod/endpoint
Custom domain endpint (Doesn't work):
https://api.{my domain}.com/endpoint
Base Path Mapping:
/endpoint endpoint:prod
All Method Auth:
Authorization None
API Key Not required
Route53:
A record as alias that points api.{my domain}.com to the cloudfront distribution domain name as alias target.
I'd really appreciate if anyone knows what's going out here.
I had met the same question several years ago and solved it by removing the 'stage' name from the URL.
the URL of gateway API seems like the following:
https://{id}.execute-api.{region}.amazonaws.com/{stage}/todos
if you have routed a custom domain https://api.xxx.com to gateway API {apiName}:{stage}, it seems like the following:
https://api.xxx.com
path: /
target: {apiName}:{stage}
Finally, the correct way to call it is to remove the stage name:
// **remove stage name!!!!**
// Right
https://api.xxx.com/todos
// Wrong
https://api.xxx.com/{stage}/todos
I found the issue is misunderstanding of how base path mapping works.
All my configurations are correct.
My API resource is not under / but under /endpoint
To use the custom domain, instead of visiting https://api.{my domain}.com/endpoint, it needs to go to https://api.{my domain}.com/endpoint/endpoint
Of course this is silly and redundant.
I have two options. I either set up the base path mapping to / instead of /endpoint or I can just user the API resource / instead of /endpoint.
I go with the latter because if base path mapping is set to /, my api.{my domain}.com will only be able to host just one API (I can still use resources under the same API, but why wasting the extra layer of abstraction?).
This seems dump but I am still glad I figured it out.
Another reason for this can be that your user, although admin, does not have a bloody CloudFrontFullAccess permissions! I just spent a couple of hours on it as I relied on serverless to do it for me and it worked perfectly on another project with different credentials, though. So double check the article! https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html
Step 1: Map the A record from subdomain.yourdomain.com to API Custom domain/API Gateway domain name(API Gateway -> Custom domain names -> tab Configuration/Endpoint Configuration).
Step 2: From API Gateway/ API Custom domain - add the api mapping. Leave "path" empty.
End point format:
Original endpoint: https://{api gateway id}.execute-api.us-west-2.amazonaws.com/prod/endpoint
Endpoint with API custom domain: https://api.yourdomain.com/**endpoint**