Building a POST API Endpoint with AWS Lambda and TypeScript
Learn how to create a POST API endpoint with AWS Lambda and TypeScript for user creation.
We'll cover the following...
A Lambda function
Now that we know what we need to build, let’s start with the /users
POST
API endpoint. A Lambda function for this will need to be defined within the
template.yaml
file as follows:
UserApiFunction:Type: AWS::Serverless::FunctionProperties:CodeUri: api-handlers/Handler: users.postHandlerRuntime: nodejs14.xEvents:UserPostEvent:Type: ApiProperties:Path: /usersMethod: postPolicies:- DynamoDBCrudPolicy:TableName: !Ref UserTable
-
We have defined a section within our YAML file with the name
UserApiFunction
with aType
property ofAWS::Serverless::Function
. -
We then define a few properties for this serverless function. The
CodeUri
property configures the root directory, and theHandler
property specifies both the file name and the function that will be used. -
In this example, we will therefore create a file named
api-handlers/users.js
that exports a function namedpostHandler
. This Lambda function will be configured by the API gateway to respond to POST methods at the URL/users
. -
We also have a
Policies
section that specifies a property namedDynamoDBCrudPolicy
. This policy will grant this Lambda function CRUD rights to the table that is specified, which in this case is a reference to theUserTable
, which appears earlier in our template definition.
Let’s now take a look at the body of the Lambda function itself:
import {APIGatewayProxyEvent,Context} from 'aws-lambda';import { dynamoDbClient } from './db-functions';export const postHandler = async (event: APIGatewayProxyEvent, context: Context) => {let response = {};try {let bodyJson = JSON.parse(<string>event.body);let username: string = bodyJson.username;let password: string = bodyJson.password;await dynamoDbClient.putItem({"TableName": "UserTable","Item": {"username": {"S": username},"password": {"S": password}},"ConditionExpression": "attribute_not_exists(#3f9c0)","ExpressionAttributeNames": {"#3f9c0": "username"}}).promise();response = {'statusCode': 200,'body': `User created`}} catch (err) {console.log(err);// return err;response = {'statusCode': err.statusCode,'body': `${err.message} : an item with this id alreadyexists`}}return response;};
-
We start by importing some types from the
aws-lambda
library and then import a variable nameddynamoDBClient
from a file nameddb-functions
. Thisdb-functions
file, which is available with the sample code, creates the database connection that we will need in all of our Lambdas and exposes it as the variabledynamoDBClient
. In this way, we have a single definition for our database connection, which can be re-used between any one of our Lambda functions. -
We then export an
async
function namedpostHandler
, which has two parameters:-
The first is named
event
and is ...
-