Skip to main content

Attaching a Domain to an API Gateway


This behaviour/feature is currently in development and has not been released yet - currently in pre-release.


In this tutorial, we'll show you how you can attach your own (pre-configured) custom domain to the API Gateway created by the @klotho::expose annotation.

Getting Started



Clone our sample apps git repo and install the npm packages for the ts-serverless-gateway app.

git clone
cd sample-apps/ts-serverless-gateway
npm install

App Overview

The ts-serverless-gateway application utilizes the following annotations:

For this tutorial, we will be focusing on the @klotho::expose annotation, as this is what will create the API Gateway for your custom domain.

/* @klotho::expose {
* id = "app"
* target = "public"
* }
app.listen(3000, async () => {
console.log(`App listening locally`)

Klotho compile the application

Let's start by compiling our TypeScript application into JavaScript.

npx tsc

Next, log in to Klotho. This will allow us to support you if you run into any issues, and give you the opportunity to shape the product in this early development stage.

klotho --login # if you haven't already

Then, compile the the app with Klotho.

klotho . --app ts-sg-domain --provider aws

The output will be similar to:

██╗  ██╗██╗      ██████╗ ████████╗██╗  ██╗ ██████╗
██║ ██╔╝██║ ██╔═══██╗╚══██╔══╝██║ ██║██╔═══██╗
█████╔╝ ██║ ██║ ██║ ██║ ███████║██║ ██║
██╔═██╗ ██║ ██║ ██║ ██║ ██╔══██║██║ ██║
██║ ██╗███████╗╚██████╔╝ ██║ ██║ ██║╚██████╔╝
╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝

Adding resource input_file_dependencies:
Adding resource exec_unit:srvless-userpost
Adding resource exec_unit:srvless-quotes
Adding resource exec_unit:srvless-userget
index.js:27:0: Found 1 route(s) for middleware 'router'
index.js:30:0: Found 1 route(s) for middleware 'userPost'
Adding resource gateway:app
index.js:27:0: Found 1 route(s) for middleware 'router'
index.js:28:0: Found 2 route(s) for middleware 'quotes'
Not adding duplicate route / for srvless-quotes. Exists in srvless-userpost
index.js:27:0: Found 1 route(s) for middleware 'router'
index.js:29:0: Found 1 route(s) for middleware 'userGet'
Not adding duplicate route / for srvless-userget. Exists in srvless-userpost
Adding resource persist_kv:quoteKV
Adding resource topology:ts-sg-domain
Adding resource infra_as_code:Pulumi (AWS)
Pulumi.ts-sg-domain.yaml: Make sure to run `pulumi config set aws:region YOUR_REGION --cwd 'compiled/' -s 'ts-sg-domain'` to configure the target AWS region.

Attaching Your Domain

Now we will retrieve your pre-configured domain by domain name, and create the mapping from your domain to the Klotho-generated restAPI or API Gateway.

Open the ./compiled/index.ts file and copy in the following highlighted code:

import * as klotho from "./klotho";

import * as aws from "@pulumi/aws";

// Use properties from 'klotho' to get references to the resources generated for id 'my-api' from the annotation.
const { restAPI, stage } = klotho.gatewaysById.get("app")!;

// Get your pre-configured API Gateway Custom Domain
const customDomain = aws.apigateway.DomainName.get(

const webDomainMapping = new aws.apigateway.BasePathMapping(
domainName: customDomain.domainName,
restApi: restAPI,
stageName: stage.stageName,
{ parent: restAPI }

Be sure to replace "" with the domain name you configured in your AWS API Gateway.

Just like that, the next time you deploy your application, your custom domain will be mapped to the API Gateway created via the klotho::expose annotation.

Deploying the application

To deploy the application, refer to the deploying guide.