Since we are using AWS cloud services, make sure you have an account for the AWS Console. Let’s start with some basic concepts of serverless computing and then will build serverless API.
Introduction
“Serverless computing is a method of providing backend services on an as-used basis”, i.e developers do not need to worry about writing the code for the server, creating the server, maintaining the server, and deploying the server. It allows developers to focus on building the application instead of configuring it.
The term “serverless” is somewhat misleading, it still requires the server to run, but all of the server space and infrastructure concerns are managed by a serverless provider or cloud provider like AWS, Google Cloud, MS Azure, etc. Developer only has to pay for the services they use.
The core of Serverless Computing
FaaS(function-as-a-service) is the core of serverless computing.
FaaS is a type of cloud computing service that allows us to execute the code in response to events without complex infrastructure. I.e Applications deployed using a serverless computing strategy are usually called serverless functions. The cloud provider gives a service wherein we can write our code or function and put it on that service and we only pay whenever the function is triggered due to an event (like user click, submit the form, etc).
Some FaaS providers are AWS lambda from AWS, Azure functions from MS, Google cloud functions from google, IBM cloud functions from IBM, etc.
Serverless Architecture in AWS
AWS provides services like AWS Lambda, Amazon API Gateway, and Amazon DynamoDB to implement serverless architectural patterns that reduce the operational complexity of running and managing applications.
An application consists of three layers- compute, integration, and Data stores, and cloud providers provide solutions for these three layers and for more.
The Frontend code is hosted on S3. Amazon S3 is a service that allows storing objects and these objects can be HTML files, JS files, etc.
Users will access the website from the S3. when the user clicks to get information the request goes through the Amazon API Gateway and in turn it is given to the AWS lambda which contains our working code. AWS lambda runs the code and fetches the information from AmazonDynamoDB and returns that output to API Gateway which in return displays on the user’s screen.
Now, let’s start using these services and creating a serverless crud application.
Prerequisite
- AWS account
- Nodejs
- AWS CLI configuration
Install Serverless Framework
To install Serverless on your machine, run the below-mentioned npm command.
npm install -g serverless
This will install serverless CLI globally on our machine.
Create Nodejs serverless Project
Now make a directory named serverless-user-rest-API and go to the directory and run the below-mentioned command.
serverless create --template aws-nodejs
This will create a boilerplate for the application which consists:
- .gitignore: This file is used to tell git which files should be kept outside of the package.
- handler.js: This declares your Lambda function. The created Lambda function returns a body with Go Serverless v1.0!
- serverless.yml: This file declares the configuration uses to create the service.
Let’s see the default configuration of serverless.yml and moving forward we will modify the serverless.yml file for configuration and the handler.js file based on the lambda function we require for the application.
It has three sections — provider, functions, and resources.
- provider: This section declares cloud provider configuration. You can use it to specify the name of the cloud provider, region, runtime, etc.
- functions: This section is used to specify all the functions that your service is composed of. A service can be composed of one or more functions.
- resources: This section declares all the resources that functions use. Like database type, table name, etc. Resources are declared using AWS CloudFormation.
Saving Data to Database
Since, we are using dynamo DB to save the record, modify the provider in the serverless.yml file by adding iamRoleStatemements as below
service: serverless-user-rest-api
frameworkVersion: "3"
provider:
name: aws
runtime: nodejs12.x
region: ap-south-1
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: arn:aws:dynamodb:ap-south-1:*:*
Now add resources to create dynamoDB table as follow:
resources:
Resources:
UsersTable:
Type: "AWS::DynamoDB::Table"
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: "users"
Now install “uuid” and “aws-sdk”using npm command and update the handler.js file and create functions for CRUD operation as below:
npm install uuid aws-sdk
createUser
"use strict";
const AWS = require("aws-sdk");
const uuid = require("uuid");
const dynamoDb = new AWS.DynamoDB.DocumentClient();
module.exports.createUser = (event, context, callback) => {
const datetime = new Date().toISOString();
const data = JSON.parse(event.body);
const params = {
TableName: "users",
Item: {
id: uuid.v1(),
fullname: data.fullname,
designation: data.designation,
createdAt: datetime,
updatedAt: datetime,
},
};
dynamoDb.put(params, (error, data) => {
if (error) {
console.error(error);
callback(new Error(error));
return;
}
const response = {
statusCode: 201,
body: JSON.stringify(data.Item),
};
callback(null, response);
});
};
listUser
module.exports.listUser = (event, context, callback) => {
const params = {
TableName: "users",
};
dynamoDb.scan(params, (error, data) => {
if (error) {
callback(new Error(error));
return;
}
const response = {
statusCode: 200,
body: JSON.stringify(data.Items),
};
callback(null, response);
});
};
getUser
module.exports.getUser = (event, context, callback) => {
const params = {
TableName: "users",
Key: {
id: event.pathParameters.id,
},
};
dynamoDb.get(params, (error, data) => {
if (error) {
callback(new Error(error));
return;
}
const response = data.Item
? {
statusCode: 200,
body: JSON.stringify(data.Item),
}
: {
statusCode: 404,
body: JSON.stringify({ message: "User not found" }),
};
callback(null, response);
});
};
updateUser
module.exports.updateUser = (event, context, callback) => {
const datetime = new Date().toISOString();
const data = JSON.parse(event.body);
const params = {
TableName: "users",
Key: {
id: event.pathParameters.id,
},
ExpressionAttributeValues: {
":f": data.fullname,
":d": data.designation,
":u": datetime,
},
UpdateExpression: "set fullname = :f, designation = :d, updatedAt = :u",
};
dynamoDb.update(params, (error, data) => {
if (error) {
console.error(error);
callback(new Error(error));
return;
}
const response = {
statusCode: 200,
body: JSON.stringify(data.Item),
};
callback(null, response);
});
};
deleteUser
module.exports.deleteUser = (event, context, callback) => {
const params = {
TableName: "users",
Key: {
id: event.pathParameters.id,
},
};
dynamoDb.delete(params, (error, data) => {
if (error) {
callback(new Error(error));
return;
}
const response = {
statusCode: 200,
body: JSON.stringify({}),
};
callback(null, response);
});
};
Add Endpoints
As our functions are ready, lets’ set up the endpoints in serverless.yml file to call those.
functions:
create:
handler: src/handler/handler.createUser
events:
- http:
path: users
method: post
cors: true
list:
handler: src/handler/handler.listUser
events:
- http:
path: users
method: get
cors: true
get:
handler: src/handler/handler.getUser
events:
- http:
path: users/{id}
method: get
cors: true
update:
handler: src/handler/handler.updateUser
events:
- http:
path: users/{id}
method: put
cors: true
delete:
handler: src/handler/handler.deleteUser
events:
- http:
path: users/{id}
method: delete
cors: true
Serverless deploy
Now, our application is ready to deploy. To deploy it use “serverless deploy or sls deploy” command. It will take a few minutes based on the internet connection and will generate the endpoints as below
We can also run it invokes these functions locally by using the command “sls invoke local -f getUser”.
Conclusion
In this blog, we understood what is serverless computing and how to use AWS services and serverless framework with nodejs. To learn more about serverless, refer
For more updates on such topics, please follow our LinkedIn page- FrontEnd Studio.