How to Build an API with TypeScript and AWS: Complete Step-by-Step Guide
By Braincuber Team
Published on April 9, 2026
Serverless architecture has revolutionized how we build APIs. Instead of managing servers, you write functions that run in response to events. Combined with TypeScript's type safety and the Serverless Framework's deployment automation, you can create production-ready APIs in minutes. This complete tutorial walks you through building two serverless APIs: one that returns city information and another that translates text using AWS Translate.
What You'll Learn:
- How to set up the Serverless Framework with AWS and TypeScript
- Creating Lambda functions with API Gateway endpoints
- Using TypeScript interfaces for type-safe data structures
- Integrating AWS SDK to access services like Translate
- Configuring IAM permissions for Lambda functions
- Deploying serverless APIs with a single command
Prerequisites
Before you begin, make sure you have:
- Node.js installed (v14 or later recommended)
- AWS account with appropriate credentials configured
- Serverless Framework installed globally
- AWS CLI configured with your credentials
If you have not set up the Serverless Framework with AWS, check out the official documentation for detailed instructions on configuring your AWS profile.
Setting Up Your Serverless Project
The Serverless Framework makes it incredibly easy to create and deploy serverless projects. Run this command in your terminal to create a new TypeScript project:
serverless create --template aws-nodejs-typescript --path my-serverless-api
Replace my-serverless-api with your desired project folder name. This command creates a complete serverless project with TypeScript configured out of the box.
Project Structure Overview
After creation, open the project in your code editor. The main files you will work with are:
| File | Purpose |
|---|---|
serverless.ts | Deployment configuration, runtime settings, function definitions |
handler.ts | Template Lambda function code |
| Other files | Configuration files, tests, dependencies |
Creating Your First Lambda Function
Now that you understand the project structure, let us create a Lambda function that returns city information. First, create a new folder called lambdas to organize your code:
Organize Your Code
Creating a dedicated lambdas folder becomes essential when you have multiple Lambda functions in one project. It keeps your codebase clean and maintainable.
Defining TypeScript Interfaces
TypeScript interfaces define the structure of your data. Create a new file called getCityInfo.ts in the lambdas folder and add this interface definition:
interface CityData {
name: string;
state: string;
description: string;
mayor: string;
population: number;
zipCodes?: string; // Optional property
}
Creating the City Data Object
Now add the city data object with actual information:
const cityData: { [key: string]: CityData } = {
newyork: {
name: 'New York',
state: 'New York',
description: 'NYC comprises 5 boroughs...',
mayor: 'Bill de Blasio',
population: 8399000,
zipCodes: '100xx–104xx',
},
washington: {
name: 'Washington',
state: 'District of Columbia',
population: 705549,
},
seattle: {
name: 'Seattle',
state: 'Washington',
population: 744955,
},
};
Creating Reusable API Response Helpers
Create a common file for API responses to reuse across your functions. First, create a folder structure lambdas/common and add an apiResponses.ts file:
const apiResponses = {
_200: (body: { [key: string]: any }) => {
return {
statusCode: 200,
body: JSON.stringify(body, null, 2),
};
},
_400: (body: { [key: string]: any }) => {
return {
statusCode: 400,
body: JSON.stringify(body, null, 2),
};
},
};
export default apiResponses;
Building the City Info Lambda Handler
Now create the complete Lambda handler that uses path parameters and returns city data:
import { APIGatewayProxyHandler } from 'aws-lambda';
import apiResponses from './common/apiResponses';
export const handler: APIGatewayProxyHandler = async (event) => {
const city = event.pathParameters?.city;
if (!city || !cityData[city]) {
return apiResponses._400({ message: 'missing city or no data for that city' });
}
return apiResponses._200(cityData[city]);
};
Configuring API Endpoints
Open serverless.ts and update the functions section to include your new Lambda with an API Gateway event:
getCityInfo: {
handler: 'lambdas/getCityInfo.handler',
events: [
{
http: {
path: 'city/{city}',
method: 'GET',
cors: true,
},
},
],
},
Adding a Translation API with AWS SDK
Now let us add a more powerful Lambda that uses the AWS Translate service. First, install the AWS SDK:
npm install --save aws-sdk
Creating the Translation Lambda
Create lambdas/translate.ts with the AWS SDK integration:
import { APIGatewayProxyHandler } from 'aws-lambda';
import * as AWS from 'aws-sdk';
import apiResponses from './common/apiResponses';
const translate = new AWS.Translate();
export const handler: APIGatewayProxyHandler = async (event) => {
const { text, language } = JSON.parse(event.body || '{}');
if (!text) {
return apiResponses._400({ message: 'missing text from the body' });
}
if (!language) {
return apiResponses._400({ message: 'missing language from the body' });
}
try {
const translateParams: AWS.Translate.TranslateTextRequest = {
Text: text,
SourceLanguageCode: 'en',
TargetLanguageCode: language,
};
const translatedMessage = await translate.translateText(translateParams).promise();
return apiResponses._200({ translatedMessage });
} catch (error) {
console.log('error in the translation', error);
return apiResponses._400({ message: 'unable to translate the message' });
}
};
Adding IAM Permissions for Translate Service
In serverless.ts, add IAM role statements to allow the Lambda to access the Translate service:
provider: {
name: 'aws',
runtime: 'nodejs14.x',
stage: 'dev',
region: 'us-east-1',
iamRoleStatements: [
{
Effect: 'Allow',
Action: ['translate:*'],
Resource: '*',
},
],
},
Adding the Translate Endpoint
Add the translate function to the functions section with a POST method:
translate: {
handler: 'lambdas/translate.handler',
events: [
{
http: {
path: 'translate',
method: 'POST',
cors: true,
},
},
],
},
Deploying Your Serverless API
With everything configured, deploy your API with a single command:
sls deploy
Testing Your API
After deployment, you will receive your API endpoint URLs. Test them using Postman or any HTTP client:
City Info Endpoint
GET request to /city/newyork returns New York city data including population, mayor, and description.
Translation Endpoint
POST request to /translate with JSON body {"text": "Hello", "language": "fr"} returns French translation.
{
"text": "This is a test message for translation",
"language": "fr"
}
{
"translatedMessage": {
"TranslatedText": "Ceci est un message de test pour la traduction",
"SourceLanguageCode": "en",
"TargetLanguageCode": "fr"
}
}
Frequently Asked Questions
What is the Serverless Framework?
The Serverless Framework is an open-source tool that simplifies deploying and managing serverless applications. It handles infrastructure configuration, deployment, and monitoring with simple commands.
Why use TypeScript for AWS Lambda?
TypeScript provides type safety, better IDE support, and compile-time error checking. Interfaces help define data structures clearly and catch errors before deployment.
How do Lambda permissions work?
Lambda functions need IAM role statements to access AWS services. In serverless.ts, the iamRoleStatements define what actions the function can perform on which resources.
What is API Gateway?
API Gateway is an AWS service that exposes Lambda functions as HTTP endpoints. The serverless.ts file configures HTTP events that automatically create API Gateway routes.
How much does serverless cost?
AWS Lambda offers a generous free tier of 1 million requests and 400,000 GB-seconds per month. API Gateway has its own pricing but both services scale automatically with usage.
Need Help Building Serverless APIs?
Our AWS-certified team specializes in building scalable serverless architectures. Whether you need help with Lambda functions, API Gateway configuration, or integrating AWS services, we can help you get there faster.
