Skip to main content

Custom Domain on API Gateway


### 1. Set up DNS records on Route53
  • If you domain name provider is not Route53, first add the domain name in Route 53.
    • Route 53 will generate NS records (name servers) which you will need to add to your domain wherever it resides. Just add the Name Servers in your domain name provider for that domain.
  • Add an Alias A record for www.chaine.dev`` that routes to chaine.dev`

2. Create a Certificate

  • Head over to Certificate Manager and create a certificate for your domain. Make sure to add the additional names:
chaine.dev
*.chaine.dev // this will cover all subdomains
www.chaine.dev

Add the end of the certificate creation process, check the button to add the certificate to Route53. If this isn't done automatically, you will need to do it manually or else your site won't be secured by the certificate.

3. Use API Gateway Custom domain

See AWS docs here if you want to do wildcard subdomains for infinite api creations without any limits from APIGW

  1. Setup Custom Domain in API Gateway, if you did multiple subdomains per environment, then create those separately (i.e. dev.api.chaineapp.com, staging.api.chaineapp.com, etc..). If you want one subdomain (i.e. api.chaineapp.com) for multiple environments, that is a little tricky to do with Serverless Framework as serverless Framework will deploy a separate api gateway resource for each stage, so you will need to do more R&D on how to do it. You can also check out this this serverless forum post, this guide,
  2. In the API Gateway console, for each domain, create an API mappings (under Custom domain names > select the custom domain > click API mappings)
  3. If you have a subdomain for each stage, just select the API and select the Stage. No need to select the Path. What this will do is for example, for dev, if you have dev.api.chaineapp.com, and apigateway path is putting a /dev, you don't need to add path and also don't need to use the /dev when making an api call. You can just make the api call like: https://api.chaineapp.com/myPath even though the path for dev in api gateway is https://api.chaineapp/com/dev/myPath. The API mapping will take care of the routing to the proper stage.
  4. Finally, make sure you have created an alias A (or CNAME) record for the subdomain path in Route53, to connect it to the proper API gateway resource.

Note, if you are using API Gateway V2, and plan on having multiple paths for a particular subdomain, you must set the path as $default, and then control the path in the custom mapping as mentioned above.

If you're using serverless framework, this is done as such:

functions:
oauth-callback:
handler: src/infra/oauth-app-callback-service/index.handler
name: ${self:service}-oauth-callback-${sls:stage}
events:
- httpApi: '*'

If you don't do this, you will get a "404 Not Found" error.

See this stack overflow for more context

Troubleshooting

404 Not Found

Most common reason for this issue is that the DNS is not properly pointing to API Gateway. To check this, use nslookup to compare the IP address of your now setup custom domain with the API Gateway domain name.

nslookup api.chaine.dev && nslookup d-abcdefch.execute-api.us-east-1.amazonaws.com

You should get an output like:

Server:     199.199.199.1
Address: 199.199.199.9#1

Non-authoritative answer:
Name: d-abcdefch.execute-api.us-east-1.amazonaws.com
Address: 40.20.1.211
Name: d-abcdefch.execute-api.us-east-1.amazonaws.com
Address: 59.20.2.222

Server: 199.199.199.1
Address: 199.199.199.9#1

Non-authoritative answer:
Name: api.chaine.dev
Address: 40.20.1.211
Name: api.chaine.dev
Address: 59.20.2.222

You may have to hit this command a few times fast since API gateway IPs are always changing.

If they don't, you need to go back and check your DNS record creation and re-do the steps to setup the custom domain.

If the address match, then your routing is setup correctly, and the issue may be with something else.

  • Try to delete your mapping, and end-point and re-deploy the API. The key here is that the custom domain should be setup first in the API Gateway before the service is deployed.

When using "Path" in the API mapping, 404 - "Not Found" is returned

If you remove the Path, and it works properly, then you need to create a stage called $default.

If you're using V2 HTTP API, make sure you don't set the route on the API level, and instead set a $default route, and control the routes on the API Mapping level.

See this stack overflow for more context

See this as well for reference

A note on custom api mapping

If you rely on path params or the path in your code, API Gateway will NOT forward the path in the api mapping, but will only forward paths that are suffixed to the path specified.

For example, if in the API Mapping you put the path oauth/app/callback

And then you make a request to oauth/app/callback/salesforce, the requestContext object will have the path in the context appear as:

 rawPath : "salesforce"
...
requestContext : {
...
http: {
method: 'POST',
path: 'salesforce',
},
}

Note that it will not include oauth/app/callback in the rawPath and path properties.