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**
Related
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.
I have an AWS API Gateway set up with a custom domain name one the format api.example.com. I have a api.example.com/prod stage and a api.example.com/dev stage, but I would also like to be able to modify the response returned on api.example.com.
What I want is very similar to how the GitHub api behaves. Where https://api.github.com/v2 access version 2 of the api, and https://api.github.com/v3 access version 3, but https://api.github.com gives a custom response.
In my case I would like to have a small static html page on api.example.com, but a custom json response (like on api.github.com) is fine, anything more helpful than {"message":"Forbidden"} would do.
I know I set up base path mappings to the dev and prod stages in the custom domain window (as my partially redacted settings below), but I would like to add a empty path as well, and have that point to another API with just a GET method on the root resource that returns a small static html page. API Gateway does not allow combining an empty base path mapping with non-empty base path mappings (for a good reason I assume), but it feel there should be some way to achieve what I am trying to set up.
Anyone who knows a way to achieve this using AWS API Gateway?
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.
I have been messing around with AWS lambda today trying some things out. I am currently trying to trigger the function from a url in a browser.
The URL looks similar to this: https://abcdef.execute-api.eu-west-2.amazonaws.com/default/test
As I understand it I can assign a custom domain to my endpoint, but can I also get rid of the path part of the url, so for example:
GET: https://example.com/
GET: https://example.com/somefile.txt
POST: https://example.com/ ['some_post_field' => 'some data']
Will all be passed to my function, or do I need to configure an EC2 instance with NGINX to proxy-pass the requests to lambda?
Any thoughts would be useful.
There are now a couple different ways you can accomplish this in AWS:
The newest (arguably coolest!) is to use Cloudfront to run your code using their Lambda#Edge service. You can completely customize your URL path and have portions used as variables like any other REST endpoint. You attach your Lambda fn to "behaviour" endpoints which give you full URL control. Its fairly deep and beyond the scope of your question to explain it all here, but read through the docs at the link provided and you'll likely see lots of stuff you like.
Another older, more expensive but more documented method is to use AWS's API Gateway as you have eluded to in your question's tags. It has a great front end console and is easy to connect API endpoints to your Lambda backend logic by attaching them to REST methods. The console helps you "variable-ize" your URL with form field data. This service helps you the most with custom domains to trigger from. Setting up custom domains is a snap in API Gateway. Be sure to use AWS's SSL Certificate Manager for free SSL certs on your custom domain too!
How you specifically setup your endpoints depends on which service you choose. Personally, given your desire to serve up different types of content, I would lean towards CloudFront, and define a "behaviour" URL for your dynamic Lambda content. If the URL request does not match one of your defined behaviours, it defaults to the Cloudfront cache/origin to serve your static assets (somefile.txt). Only matches go to your attached Lambda fn with form data. Very slick!
A lot of example Lambda#Edge fn's are available here.
I have used both and have clients on both now. Lambda#Edge is ridiculously faster and less expensive, BUT is less documented, has a steeper learning curve, and console is not nearly as helpful. I would honestly try both to see which fits your situation and experience level best. Both will get the job done. EC2 is most definitely NOT needed (nor desired perhaps). Hope that helps — good luck!
Instead of directly exposing the Lambda function via URL, expose it through AWS API Gateway where you can define your own paths and map to a Domain.
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.