Building a Full-Stack AWS Serverless Architecture, Part 2: Backend Services

Building a strong, reliable backend framework is an important part of any software application. In our previous post, we described our example client problem and some of the given constraints. Besides outlining the problem, we discussed the frontend AWS services we used to start building our serverless architecture.

Next, we will do the same for some AWS services to help solve the challenge of storing and managing the package data. Just like in part one, our goal is to use services that are serverless and use the AWS pay-as-you-go model to cut ongoing costs.



One of the responsibilities of the backend is to fulfill the requests coming from the client. One option is to use AWS Lambda to handle all incoming requests. Lambda is the most popular compute service AWS offers. It provides an easy way for applications to run code without needing to worry about infrastructure management or a fluctuating workload.

The cost is based on the number of requests you make and the length of each instance. It is very easy to set up and can quickly scale to any application workload. We decided to use API Gateway to route all requests to Lambda functions, which would each have a distinct purpose. One function may return package information, while another could generate shipping cost reports for an office.

Limitations to be aware of when using Lambda are the maximum fifteen-minute length and 50 MB zipped deployment package size. For our use case, all requests involving the status of a package or a list of packages sent by an office should never take anywhere close to fifteen minutes. That makes it a great choice for all of our computing needs.

Data Storage


One of the most important aspects of any system is how the data is stored. We have to digest and store a lot of data and make sure it’s always ready to send back out to users. This would include data about a package, its starting, current, and final locations, who sent and received the package, and any relevant cost information.

One option for storing all of this data is DynamoDB, Amazon’s NoSQL database service. Dynamo stores all data as key/value pairs, which means that you can’t have any kind of joins between different tables. One advantage is that there is no database management required.

Aurora Serverless

The other database option we have is Aurora Serverless. This is an RDS (Relational Database Service) instead of a NoSQL database like Dynamo. One of the major questions we had while choosing between the two was whether we needed a relational or NoSQL database. The main advantage of Aurora for us was the flexibility it provides for queries. Because the data is more structured, it would be easier and quicker for developers to write custom queries compared to a NoSQL database.

We ended up choosing to use Aurora over Dynamo in order to provide that flexibility in the long run. The cost was not a big concern, as both services use the pay-as-you-go model. We expected that, in the future, we would want to add more complex features. And having the data in a more structured database would allow us to develop them quickly and make it easier for whoever would be working on it.

If you’d like to read more about how to choose the right database for your application, we found this article helpful when weighing our options: Choosing a Database for Serverless Applications.

Application Integration

API Gateway

As described earlier, we found we could use API Gateway and Lambda to manage calls to our API and provide security and performance to our backend. API Gateway acts as the central point between traffic from the front end and logic and data in the backend.

Integrating this service with Cognito to enforce authorization around our APIs was a nice plus as well. Overall, we ended up using this service as the main entry point similar to the example described in this AWS architecture blog post.


Amazon’s Simple Notification Service (SNS) allows you to handle messaging between applications or between an application and its users. For our system, we could use SNS to send email or text notifications to users when their package is sent or received at an office. We could also use this service to send out alerts to users when one of their packages runs into a delay in transit. While notifications were not a requirement for our system, we felt it would be a valuable feature, and SNS appeared to be quick and easy to integrate.

There are many options when it comes to building the backend for a web or mobile application. This is certainly not an exhaustive list of considerations when researching services.

Depending on your application, you’ll have different priorities around cost, security, maintenance, complexity, etc. For us, going through the process of researching services with a client problem in mind helped us build confidence and experience working in the AWS ecosystem.