...

/

Building a POST API Endpoint with AWS Lambda and TypeScript

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.

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:

Press + to interact
UserApiFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: api-handlers/
Handler: users.postHandler
Runtime: nodejs14.x
Events:
UserPostEvent:
Type: Api
Properties:
Path: /users
Method: post
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref UserTable
  • We have defined a section within our YAML file with the name UserApiFunction with a Type property of AWS::Serverless::Function.

  • We then define a few properties for this serverless function. The CodeUri property configures the root directory, and the Handler 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 named postHandler. 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 named DynamoDBCrudPolicy. This policy will grant this Lambda function CRUD rights to the table that is specified, which in this case is a reference to the UserTable, which appears earlier in our template definition.

Let’s now take a look at the body of the Lambda function itself:

Press + to interact
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 already
exists`
}
}
return response;
};
  • We start by importing some types from the aws-lambda library and then import a variable named dynamoDBClient from a file named db-functions. This db-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 variable dynamoDBClient. 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 named postHandler, which has two parameters:

    • The first is named event and is ...