I recently deployed a React web app, Flexy, using an AWS Serverless infrastructure, running on Lambda functions, API Gateway and DynamoDB. This isn’t the first app I have built using this model, but this is the first time I have documented it and will release the details of the app, which this article will cover.
I’m an advocate of serverless technologies for many reasons, the biggest being that it allows developers such a greater focus on the business logic and fundamental consumer facing aspects of the application instead of their time on those matters being reduced by issues relating to resources which make up the supporting back end architecture. For Flexy, this is exactly what I have been able to do. Compared to other applications I have in production where if I suddenly get a spike in traffic I will need to go and fix breakages and rearrange the load balancers and scaling groups in the architecture’s make-up, with Flexy these resources are on-demand and will require, at most, a click of a button to increase capacity limits. Now with that being said, let’s dive deeper into what I have needed to build for this app.
The UI is a React app with its state being populated from REST calls to AWS’ API Gateway. My apps configuration consisted of two pretty interesting libraries. Firstly, the styled-components package. I wrote about this package in a previous article and would recommend it for your styling in React. The second was the AWS-Amplify package for which I used it only for the resources I know I will never change, so in this case, a Cognito user pool and one API Gateway endpoint communicating with the pool. All of my previous serverless apps had been built either from scratch or through my own Cloud Formation templates, so I wanted to give Amplify a try. It is very useful, and certainly convenient for smaller apps. But building serverless apps from scratch is fun. Even for Flexy, which is a pretty in-comprehensive application. Here is a very simple diagram outlining Flexy’s architecture:
I divided the communications between four Lambda functions, two DynamoDB tables and two API Gateway resources.
Firstly, the Lambda functions. Each action available to the user on the front end has its own function to handle the requested operation. GET all, GET user trips, PUT, DELETE. I have completely decoupled the operations from one another, with each abiding by the microservices principle of ‘doing one thing and doing it well’.
The DynamoDB tables consist of one specifically for Users and the other for Trips, with the users cognito username saved and used for querying that one.
The API Gateway endpoint separates by specific resource, although Amplify generates ‘ANY’ resources if you use that. I didn’t go that route, however.
The mapping templating and models API Gateway offers are incredibly useful tools, they can be tricky to keep the rest of the app updated with, however. And this isn’t just from the developer side of things. The templating produces some unexpected behaviour at times. Take for example the mapping template for integration requests when using Cognito. Why doesn’t the values from the $context object work here?
Even with pretty diligent planning, I am growing accustomed to expect some hiccups when using more advanced body mapping templates with API Gateway.
This app certainly isn’t a huge scaled application, so serverless may seem a bit excessive. And yet in some ways this is the point of it to begin with. The size of the app really doesn’t matter. Since much of the resources are provisioned for you, just go build whatever you want. I can now go and build a more comprehensive app, perhaps a native version of Flexy with much more features, and the concerns for me as the developer are still much more focused towards business logic. The architecture I have put together for this app doesn’t really need to change.
If you like my work, take a look at my Portfolio or reach out on LinkedIn.
I always try to take time to provide thanks to developers whose resources and material I have used to get my work to where it is. For this app, I reused a lot of designs on the front end which I initially found through the work of an immensely talented designer, Jonas Schmedtmann.