Having a professional, branded API endpoint is essential for modern applications - especially when you want your users to interact with something memorable like api.yourcompany.com rather than the default, randomly generated AWS endpoint like https://d-abc123xyz.execute-api.us-east-1.amazonaws.com
.
If you have read any of my previous blogs, you'll know how much I love API Gateway - and this is another reason too! This is particularly nice to keep branding consistent if you are allowing your users to directly consume the API in their own applications.
So let's take a look at how we can provision an API Gateway with a custom domain - all using AWS CDK.
✍️ Define some CDK
Unfortunately, like with many AWS services, CDK doesn't always provide the most elegant L2 constructs for every scenario. However, the API Gateway constructs are quite mature, so we'll be working with a nice combination of L2 constructs and some manual configuration.
Before we jump into the CDK itself, the following examples assume that you have a few things already provisioned and in place:
- A registered domain name (can be managed by Route 53 or external registrar)
- A hosted zone in Route 53 for your domain
Provision the cert
We must create a new TLS certificate for usage on our API Gateway with our custom domain. The following creates the certificate, and specifies that DNS records are going to be used to verify it:
const domainName = "api.yourcompany.com";
// Certificate for custom domain
const certificate = new certificatemanager.Certificate(
this,
"ApiCertificate",
{
domainName,
validation: certificatemanager.CertificateValidation.fromDns(),
}
);
Provision API Gateway
Now for the main event - creating our API Gateway with a custom domain. There are a couple of approaches here, but I'll show you the most straightforward method using the RestApi construct with domain configuration:
// API Gateway
const api = new apigateway.RestApi(this, "Api", {
restApiName: "Custom Domain API",
domainName: {
domainName,
certificate,
basePath: "v1", // Optional
},
});
// Sample resource and method
api.root.addMethod("GET");
The above provisions a new gateway that consumes the certificate and the custom domain name that we want to specify. Additionally, it also specifies a basePath that simply prefixes the routes that you define on your API gateway - example: /v1/users/
.
Finally, it also adds a HTTP GET
method onto the root definition of the gateway.
DNS changes
The final piece of the puzzle is configuring the new A record within your Route 53 hosted zone. This will effectively just point to the API gateway and that finalises the alias.
const hostedZoneId = "Z1234567890";
// Route53 alias record
const hostedZone = route53.HostedZone.fromHostedZoneAttributes(
this,
"HostedZone",
{
hostedZoneId,
zoneName: "yourcompany.com",
}
);
new route53.ARecord(this, "ApiAliasRecord", {
zone: hostedZone,
recordName: "api",
target: route53.RecordTarget.fromAlias(new targets.ApiGateway(api)),
});
As I had mentioned previously, this example assumes that you already have a hosted zone defined, and the call above references the hosted zone by the ID. This aliases our API gateway with the api
subdomain.
🚀 Deploy and Test
Once you've got everything configured, deploy your stack:
cdk diff
cdk deploy
Your diff should show resources similar to:
Resources
[+] AWS::ApiGateway::RestApi custom-domain-api customdomainapi
[+] AWS::ApiGateway::DomainName custom-domain-api/Domain customdomainapiDomain
[+] AWS::ApiGateway::BasePathMapping custom-domain-api/PathMapping customdomainapiPathMapping
[+] AWS::Route53::RecordSet api-alias-record apializasrecord
After deployment, you should be able to access your API using your custom domain:
curl https://api.yourcompany.com/
You may need to configure an integration in behind the scenes to test this fully end-to-end, and if you do not have an integration already set up, a simple one that you can add is a Lambda integration.
And that's it!
Conclusion
Remember to cdk destroy your stack when you're done testing to avoid unnecessary costs!
Professional URLs: Creating a custom domain for your API Gateway transforms generic AWS URLs into professional, branded endpoints that users can trust and remember.
Flexible Configuration: The combination of domain names, base path mapping, and Route 53 records provides extensive flexibility for organizing multiple APIs under a single domain.
SSL/TLS Security: Built-in HTTPS termination with AWS Certificate Manager ensures your API communications are secure without additional configuration overhead.
Top comments (0)