Backend for SPA and Mobile App (Serverless)

Introduction

Single Page Applications (SPAs) and mobile apps can use APIs to communicate with a server and retrieve or manipulate data. This can be used to display data on the frontend, or to send data to the server to be stored.

This article constitutes a component of a comprehensive collection of web architecture pattern references.

Single Page Application Frontend
Backend for SPA and Mobile App (Managed Services)
Backend for SPA and Mobile App (Serverless)
Multi Page Application (Integrated Web)
Single Page Application with Worker Process

API Technologies

For the backend of a mobile app or SPA, various API technologies can be used, including:

  • REST (Representational State Transfer): This is a popular, lightweight, and scalable API technology that uses HTTP requests to perform operations on resources.

  • GraphQL: This is a newer API technology that provides a more flexible and efficient alternative to REST, allowing clients to request only the data they need.

  • gRPC: This is a high-performance, open-source framework for building scalable APIs. It uses the Protocol Buffers data format and supports a variety of programming languages.

  • SOAP (Simple Object Access Protocol): This is an XML-based protocol for exchanging structured information in the implementation of web services.

These API technologies can be used to create APIs that can be consumed by mobile apps or SPAs. The choice of technology depends on the specific requirements of the project, such as performance, security, and data exchange requirements.

Architecture

The architecture for all the above API technologies will be almost the same. We are considering the REST API for now as that is the most popular option.

There are different solutions and services to host the SPA Backend on cloud, here are some of the popular:

  • VM (eg: EC2)
  • Container Services (eg: ECS)
  • Managed Services (eg: Elastic Beanstalk)
  • Serverless (eg: Lambda)
  • Kubernetes (eg: EKS)

Among the above list, we’re covering only Serverless and Managed Services.

Serverless

Using a serverless architecture has several benefits, including:

  • Cost-effectiveness: Serverless architectures allow you to pay only for the resources you actually use, making it a cost-effective solution for both small and large scale applications.

  • Scalability: Serverless architectures automatically scale to meet changing demand, eliminating the need for manual scaling and allowing organizations to focus on delivering value to their customers.

  • Reduced operational overhead: By outsourcing infrastructure management to the cloud provider, organizations can reduce operational overhead and focus on writing code and delivering features.

  • Improved time-to-market: Serverless architectures allow developers to focus on writing code, rather than managing infrastructure, improving time-to-market for new features and applications.

  • Flexibility: Serverless architectures provide a flexible and modular approach to building applications, allowing organizations to easily modify and extend their applications as needed.

  • High availability: Serverless architectures are designed to be highly available, with automatic failover and replication to ensure that applications remain available even in the event of a failure.

  • Improved security: Serverless architectures provide built-in security features, such as automatic patching and secure data storage, reducing the security burden on organizations.

  • Easy integration with other services: Serverless architectures integrate seamlessly with other cloud services, allowing organizations to leverage the full suite of cloud services to build and deploy their applications.

Backend Architecture (Serverless)

A complete architecture diagram with frontend and backend would be as follows:

SPA Architecture (Serverless)

Next – Multi Page Application (Integrated Web)

Previous – Backend for SPA and Mobile App (Managed Services)

Home

AWS Serverless and DynamoDb Single Table Design using .Net 6 – Part 2

Introduction

This is a continuation of the previous article AWS Serverless and DynamoDb Single Table Design using .Net 6 – Part 1. In this part we’re going to create a sample Serverless application using DynamoDb and deploy that on AWS Lambda.

Tools

Configure

Configure the AWS Toolkit using the link. While creating the IAM user make sure to attach the below policies

AWS Policies
Image: 1 

We’ll be using this user for creating the serverless application and deploying the same from Visual Studio or dotnet tools command line interface.

Why Serverless

Serverless solutions offer technologies for running code, managing data, and integrating applications, all without managing servers. Serverless technologies feature automatic scaling, built-in high availability, and a pay-for-use billing model to increase agility and optimize costs. These technologies also eliminate infrastructure management tasks like capacity provisioning and patching, so you can focus on writing code that serves your customers. Some of the popular serverless solutions are AWS Lambda and Azure Functions.

Development

AWS Toolkit for Visual Studio provides many built-in templates for creating AWS based serverless applications quickly.

Create a new project from Visual Studio and type ‘serverless’ in the search box and select `AWS Serverless Application (.NET Core – C#).

Image: 2

Enter the project name and continue.

Image: 3

Then select the ASP.NET Core Web API blueprint from the selection and click Finish

Image: 4

Once the project is ready in Visual Studio, you can see a file called serverless.template. This is AWS CloudFormation Serverless Application Model template file for declaring your Serverless functions and other AWS resources. Make sure to add two policies( AWSLambda_FullAccess and AmazonDynamoDBFullAccess) as shown below: These permissions are required for the Lambda to Read and Write to DynamoDb

Image: 5

Then add the below Nuget packages:

AWSSDK.DynamoDBv2Newtonsoft.JsonSwashbuckle.AspNetCore.SwaggerGenSwashbuckle.AspNetCore.SwaggerUI

Create an Interface called IEmployeeDb to define the methods

public interface IEmployeeDb{   Task<IEnumerable<EmployeeModel>> GetAllReporteesAsync(string empCode);   Task<EmployeeModel> GetEmployeeAsync(string empCode);   Task SaveAsync(EmployeeModel model);   Task SaveBatchAsync(List<EmployeeModel> models);}

Create a class to implement the IEmployeeDb interface. The constructor would look like the below:

public EmployeeDb(ILogger<EmployeeDb> logger, IWebHostEnvironment configuration){   //Comment out the below four line if you're not using the DynamoDb local instance.   if (configuration.IsDevelopment())   {      _clientConfig.ServiceURL = "http://localhost:8000";   }   _client = new AmazonDynamoDBClient(_clientConfig);   _context = new DynamoDBContext(_client);   _logger = logger;}

We configured the ServiceURL to point the localhost in case we’re using DynamoDb local instance. We also initialized the AmazonDynamoDBClient and DynamoDBContext. We’ll be mainly using the Highlevel API called DynamoDBContext for reading and writing data from DynamoDb.

The below methods are responsible for writing/saving the data:

public async Task SaveAsync(EmployeeModel model){   await SaveInDbAsync(GetUserModelForSave(PrepareEmpModel(model)));   await SaveInDbAsync(GetReporteeModelForSave(PrepareEmpModel(model)));}private async Task SaveInDbAsync(EmployeeModel model){   await _context.SaveAsync(model);   _logger.LogInformation("Saved {} successfully!", model.EmployeeCode);}private EmployeeModel PrepareEmpModel(EmployeeModel model){   model.EmployeeCode = model.EmployeeCode?.ToUpper();   model.ReportingManagerCode = model.ReportingManagerCode?.ToUpper();   return model;}

When saving a record, this method will actually insert two objects, one for user type and the other for reportee type. We discussed the reason and logic for creating two entries in the previous part.

In the below method we implemented the logic for fetching the employee by EmployeeCode:

public async Task<EmployeeModel> GetEmployeeAsync(string empCode){   var result = await _context.LoadAsync<EmployeeModel>(empCode.ToUpper(), empCode.ToUpper());   if (result != null)      result.ReportingManagerCode = ""; //ReportingManagerCode was same as EmployeeCode, so just remove it   return result;}

Next method will cover the logic for fetching the reportees by EmployeeCode:

public async Task<IEnumerable<EmployeeModel>> GetAllReporteesAsync(string empCode){   var config = new DynamoDBOperationConfig   {      QueryFilter = new List<ScanCondition> {         new ScanCondition("Type", ScanOperator.Equal, "Reportee"),         new ScanCondition("LastWorkingDate", ScanOperator.IsNull)      }   };   var result = await _context.QueryAsync<EmployeeModel>(empCode.ToUpper(), config).GetRemainingAsync();   return PrepareReporteeReturnModel(result); //swap the EmployeeCode and  ReportingManagerCode and return}

All the other code fragments and complete solution can be downloaded from the GitHub repository.

Once you complete the development you need to create a DynamoDb table in your AWS account. There are many ways to create a service in AWS. You can use CLI, Console, SDK or even Visual Studio Toolkit. Below is the CLI command for creating the table and setting up the pk and sk.

aws dynamodb create-table --table-name employees --attribute-definitions AttributeName=EmployeeCode,AttributeType=S         AttributeName=ReportingManagerCode,AttributeType=S --key-schema AttributeName=EmployeeCode,KeyType=HASH AttributeName=ReportingManagerCode,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 --table-class STANDARD

Now you can deploy the serverless application either using Visual Studio or dotnet tools. To deploy using Visual Studio, right click on the project and select the Publish to AWS Lambda button.

To deploy using dotnet tools you need to follow the below steps in the command line.

dotnet tool install -g Amazon.Lambda.Toolscd "AWSServerlessDynamoDb/AWSServerlessDynamoDb" #or whatever the folderdotnet lambda deploy-serverless

After successful deployment, you will get a Lambda endpoint(ApiURL)  as below:

Image: 6

You can access your SwaggerUI by adding /swagger in the above url and you can test the APIs.

Complete source code can be found here.

Happy coding!!