26

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.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
jlai
  • 909
  • 1
  • 10
  • 17
  • Did you also setup a `Route53-Record-Set` which points to the `CloudFront-Distribution`? – MaiKaY Jul 04 '17 at 05:42
  • @MaiKaY yes. I have an A record as alias for api.{my domain}.com. The alias target is the CloudFront distribution domain name – jlai Jul 04 '17 at 05:54
  • 1
    I guess you need to change your `BasePath Mapping` to: `/ endpoint:prod`. Or try with the existing `BasePath Mapping` to access `https://api.{my domain}.com` – MaiKaY Jul 04 '17 at 06:06
  • @jlai can you please mention the error you get or your request is not reaching the API gateway – Ali Jul 04 '17 at 06:50

4 Answers4

35

I had met the same question several years ago and solved it by removing the 'stage' name from the URL.

  1. the URL of gateway API seems like the following:
https://{id}.execute-api.{region}.amazonaws.com/{stage}/todos
  1. 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}
  1. 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
Chongsheng Sun
  • 441
  • 5
  • 5
  • 5
    OMG YES! This was exactly my problem!!! [I wrote about it here.](https://www.reddit.com/r/aws/comments/m6d5l1/comment/hmamdgt/?utm_source=share&utm_medium=web2x&context=3) Basically, the stage name is also replaced by the custom domain. (Note: I wish your answer was a bit clearer, because I didn't get it the first time I read it.) – ADTC Nov 27 '21 at 17:34
  • 1
    Boom!! just removed stage name (dev) and it worked!!! – Ameer Ul Islam Dec 29 '21 at 09:19
26

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.

jlai
  • 909
  • 1
  • 10
  • 17
  • It's not clear why you would expect that a base path of `/endpoint` with a resource named `/endpoint` would result in any behavior *other* than requiring requests to go to `/endpoint/endpoint`, since the resource is accessed at base-path + resource. – Michael - sqlbot Jul 04 '17 at 14:23
  • 6
    I actually set up the api gateway using lambda's template and the template automatically places it under the name of the API instead of API's root. This is my first time using it so I didn't expect this behavior. I was anticipating that the resource is created right under the root of API, meaning the name of the API should just be the name of API and the root is used for the very first resource by default. – jlai Jul 04 '17 at 19:24
  • 1
    I see what you mean. – Michael - sqlbot Jul 05 '17 at 00:26
  • I ran into the same issue, also not realizing that lambda creates a nested resource in the gateway. I was receiving {"message":"Missing Authentication Token"} – Skyler Feb 20 '19 at 03:50
  • yeah, jlai. Im agree with you. my api was "abcd12345.execute-api.us-east-1.amazonaws.com/Dev/resource" but when i create custom api domain name and add only stage, not path, then i can only access it by example.com/resource. its really silly. – k'' Oct 15 '20 at 04:14
  • it wasn't clear to me either, thank you, can't believe I missed this. – code4cause Feb 28 '23 at 04:31
0

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

Jan Sila
  • 1,554
  • 3
  • 17
  • 36
0

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**

crystal
  • 185
  • 1
  • 4