Open In App

Building a Serverless Blog with AWS Lambda and API Gateway

AWS Lambda is a serverless computing service offered by AWS. It enables you to run code in response to events without the need to manage servers. This event-driven service charges you based on actual compute time, making it cost-effective. Lambda supports various programming languages, scales automatically, and seamlessly integrates with other AWS services, making it an ideal choice for building dynamic applications with minimal operational overhead.

Amazon API Gateway

Amazon API Gateway works hand-in-hand with AWS Lambda. It makes it easy to create and manage APIs, acting as a bridge between applications and backend services. It ensures security through authentication and authorization and keeps an eye on how the API is used. Plus, it protects against misuse with features like rate limits. This service is crucial for building safe and scalable APIs that connect different parts of a system smoothly. When combined with AWS Lambda, it’s a powerful duo for creating dynamic, event-driven applications.



In order to perform these operations, we have to write our backend logic. We will create a Lambda Function for that. Then we build a Blog API using AWS API Gateway and integrate that with our lambda function. When a user invokes our Blog API, API Gateway routes the request to our Lambda function. The Lambda function interacts with DynamoDB and returns a response to API Gateway. API Gateway then returns a response to the end user.



Create a DynamoDB Table

DynamoDB is a powerful, fully managed AWS NoSQL database service offered by AWS. It’s designed for high performance and easy scalability. Unlike traditional databases, it doesn’t require predefined table structures. It ensures fast access to data, offers features like backups and fine-grained access control, and is cost-effective.

Steps To Create A Table

Create a Lambda Function

Now, we will create a lambda function for the backend of our API. The lambda function need to handle the operations for creating, reading, updating and deleting items in DynamoDB.

Steps to create a Lambda Function

const AWS = require("aws-sdk");
const dynamoDB = new AWS.DynamoDB.DocumentClient({
region: ‘us-east-1’,
apiVersion: ‘2012-08-10’,
});

exports.handler = async (event, context, callback)=>{
if(event.id === undefined){
if(event.httpMethod === "GET"){ // retrieve all blogs from database
const params = {
TableName: "blog-database"
}
await dynamoDB.scan(params).promise().then((data)=>{
const restructuredData = data.Items.map((newData)=>{
return ({"blogId": newData.blogId, "title": newData.title, "content": newData.content, "author": newData.author});
});
callback(null, restructuredData);
}).catch((err)=>{
callback(err);
})
}
else if(event.httpMethod === "POST"){ // create a blog in the database
const params = {
Item: {
blogId: "blog_"+Math.random(),
title: event.title,
content: event.content,
author: event.author
},
TableName: "blog-database"
}
await dynamoDB.put(params).promise().then((data)=>{
callback(null, data);
}).catch((err)=>{
callback(err);
})
}
else{
callback(null, `Method: ‘${event.httpMethod}’ is not allowed`);
}
}
else{
if(event.httpMethod === "GET"){ // retrieve a particular blog from database
const params = {
Key: {
blogId: event.id
},
TableName: "blog-database"
}
await dynamoDB.get(params).promise().then((data)=>{
const restructuredData = {
"blogId": data.Item.blogId,
"title": data.Item.title,
"content": data.Item.content,
"author": data.Item.author
}
callback(null, restructuredData);
}).catch((err)=>{
callback(err);
})
}
else if(event.httpMethod === "PATCH"){ // updade a particular blog in database
const params = {
Key: {
blogId: event.id
},
UpdateExpression: `set ${event.key} = :value`,
ExpressionAttributeValues: {
":value": event.value
},
TableName: "blog-database",
ReturnValues: "UPDATED_NEW"
};

await dynamoDB.update(params).promise().then((data)=>{
callback(null, data);
}).catch((err)=>{
callback(err);
})

}
else if(event.httpMethod === "DELETE"){ // delete a particular blog from database
const params = {
Key: {
blogId: event.id
},
TableName: "blog-database"
}
await dynamoDB.delete(params).promise().then((data)=>{
callback(null, data);
}).catch((err)=>{
callback(err);
})
}
else{
callback(null, `Method: ‘${event.httpMethod}’ is not allowed`);
}
}
}

Setup API Gateway

Now, we will create our Blog-API. We will use the API Gateway service. Let’s understand what we are gonna create, what will happen behind the scenes of the API —

  • We will create an API that will have the following routes:
    • /blogs POST to create a blog, GET to fetch all blogs
    • /blogs/:id GET to fetch a particular blog
    • /blogs/:id PATCH to update a particular blog
    • /blogs/:id DELETE to delete a particular blog

Our backend logic (lambda) is created earlier. So, we just have to create these API routes and connect those with our lambda function.

To achieve this, follow the steps below —

Login your AWS account and go to API Gateway Service. Click upon the “Create API” button and choose REST API (not Private) and click upon the “build” button to create a AWS REST API.

You can see 3 types of API Endpoints —

Regional: It is intended for the clients in the same region. When clients are running in the same regions i.e. API is intended to serve a small number of clients with high demands, Regional API reduces connection overhead.

Edge Optimized: It is best for geographically distributed clients. API requests are routed to the nearest CloudFront Point of Presence(POP).

Private: It is an API endpoint that can only be accessed from my Amazon Virtual Private Cloud (VPC).

Let’s create an API of Regional Endpoint. Now our API is created. We just have to define all the HTTP methods our API will react to and all the resources our API will use.

Now create a resource providing resource name & resource path. Here, we are creating a resource with name “blogs” and path “blogs”.

blogs resource

Now, inside the Integration Request, go to Mapping Template and check “When there are no template defined(recommended)” and create a mapping template with “application/json‘ and generate template using “Method Request Passthrough”. You can replace all commands with the following code & save the code. Yeah! GET request on /blogs route will now be handled by our lambda function.




{
    "httpMethod": "$context.httpMethod"
}




#set($inputRoot = $input.path('$'))
{
  "httpMethod": "$context.httpMethod",
  "title" : "$inputRoot.title",
  "content" : "$inputRoot.content",
  "author" : "$inputRoot.author"
}




{
    "httpMethod": "$context.httpMethod",
    "id" : "$input.params().path.id"
}




#set($inputRoot = $input.path('$'))
{
    "id" : "$input.params().path.id",
    "httpMethod": "$context.httpMethod",
    "key" : "$inputRoot.key",
    "value" : "$inputRoot.value"
}




{
    "id" : "$input.params().path.id",
    "httpMethod": "$context.httpMethod"
}

Testing our Blog API

FAQs On Building a Serverless Blog with AWS Lambda and API Gateway

1. Why Use AWS Lambda And API Gateway For Building A Serverless Blog?

AWS Lambda and API Gateway are serverless computing services provided by Amazon Web Services (AWS). They enable you to run code in response to events and create APIs without the need to manage servers. This approach reduces operational overhead, scales automatically, and allows you to pay only for the resources you consume.

2. Can I Handle User Authentication And Authorization In a Serverless Blog?

Yes, You can use AWS Cognito, a service that provides authentication, authorization, and user management. It integrates seamlessly with AWS Lambda and API Gateway, allowing you to secure your endpoints and manage user accounts.


Article Tags :