Monolithic vs. Microservices vs. AWS Serverless Architecture for e-commerce
Hello there! In this post we will compare 3 different perspectives on creating an e-commerce website.
We will review the advantages, disadvantages, and differences between a monolithic architecture, the usage of microservices, and going for a serverless architecture.
But first of all, we need to define the core features of the e-commerce application we will model, independently of the architectural decisions we make.
Note: We will focus only on the end-user and not the administrative application.
Core features for an e-commerce application
- Product catalog: We need to show our users a list of products and the detail of each one. In the implementation we should consider a product title, a description, multiple images, tags, and the available stock, among others.
- Shopping cart: This functionality allows users add products to their cart. We should consider at least adding and removing products, changing the number of items, and storing temporary carts for future use.
- User module: This helps our clients manage their personal data, delivery addresses, track purchases, view purchase history, and review stored shopping carts. It could also include functions for registering new users.
- Login module: Functionalities for handling authentication and authorization to the application, including a password recovery module.
- Order processing: This module is responsible for validating stock, user data, and delivery addresses. It must communicate with external services for handling payment processes.
Same app, different approaches
Now, we can see how different it can be to implement a monolithic architecture compared to a microservices approach, and finally, the use of serverless services.
Monolithic architecture
In a monolithic application, a single service is responsible for handling the three core parts of the application:
- The user interface
- The business logic
- The data interface
We can consider a different service for data storage, most likely a database server.
How can the user access different functionalities in an e-commerce app?
When it comes to accessing various functionalities in an e-commerce app, different user interfaces are shown when the user navigates to different URLs based on menus and a home or main page.
The web server handles redirection, whether it’s a request to a file (e.g., catalog.php) or some sort of URL rewriting (e.g., catalog.php would be called when the path is /catalog).
The user interface layer communicates with the different modules (all on the same server) to perform the business logic.
If it’s necessary to retrieve or store data, the business logic will use the data interface to communicate with the database service and handle various queries accordingly.
A simple diagram would look like the one below, where each module in the backend is represented as a box. Remember, they are all in the same server.
Advantages of the monolithic approach
- Fast to start developing: Only one server is needed to handle the user interface, backend, and data interface, making the environment ready for deployment quickly.
- Simple Infrastructure Management: The whole application runs on the same server, eliminating the need for complex architecture or management practices.
- Uniform application: The platform is likely written using the same programming language or framework, making the application uniform and easy to maintain.
Challenges
- Scaling Issues: If one of the modules or functionalities requires more resources, we need to scale out the entire server. For example, handling a large number of products with complex filters could demand more CPU and memory. To address this, we must increase the server size.
- Single Point of Failure: If the server fails, all the application goes down.
- Maintenance Complexity: Adding new functionalities or fixing errors can become challenging. For any update, whether it’s fixing errors, adding features, or making minor changes to the interface, the whole platform needs to be deployed. And this can be prone to errors and could lead to uptime issues.
Using Microservices
The microservices architectural approach focuses on modularity and the independence of components. What does this means?
We build our application by considering separate environments, each self-managed, scalable, atomic, and replaceable.
The core functionalities will remain almost the same as the monolithic approach, but each component operates independently from the others.
However, we need to add a key distinctions: We will need a component for managing the routing to the different microservices, known as the API Gateway. Also, each component will have its own database for its specific use.
An architectural overview of the e-commerce platform is shown next.
As a first sight, not so different from the monolithic service. But the implementation will be very distinctive.
Advantages of the Microservices Approach
- Scalability: Each component can scale independently, making the entire application more flexible in handling different loads and service needs.
- Modularity: Each component can be refactored, fixed, or fully replaced to suits new business needs.
- Fault Isolation: If one of the components fails, the application keeps running, and the specific microservice can be handled properly.
- Fast Development for medium to big projects and teams: Development speed can be enhanced as each component can be built independently, allowing different development teams to work more agilely.
- Technology Diversity: Each microservice can be built using different technologies that best fit the component’s needs.
Challenges
- Complex Management: Application management becomes more challenging as each piece needs to fit into the overall system.
- Potential Overhead for Small Teams: For a small application with limited functionalities or a small team with a restricted number of developers, the application’s fragmentation can lead to confusion and complications.
- Forward Thinking Required: The architect and development team need to plan for the future, defining each component as a self-contained element. They likely need to define a list of APIs or interfaces to facilitate communication between the different microservices.
Serverless Approach
First, we need to define what is serverless. It’s not the absence of servers.
Instead, it’s one of the great benefits obtained from cloud providers, where, as architects or developers, we don’t manage the servers associated with the service we want to use. We only focus on some limited configuration and on using it.
We can compare it using a simple but relevant example. Let’s suppose we want to store files and give our users the possibility to download these files through the internet.
Manually, we would need to configure a server and give the proper access using different types of protocols according to what we need.
It could be FTP, SSH, or even HTTP. Then, the user can download or access the file.
But, in terms of the server, apart from the initial configuration, we need to maintain this server, manage scaling if we have an unexpected amount of traffic, handle the security of the environment, updates, and patches, among other tasks.
Well, with a serverless service we only need to use this service. The administration is minimal.
In terms of AWS services, I am talking about creating an EC2 instance for storing files compared with the usage of a serverless service like S3.
How about our e-commerce application?
Note: We will use AWS serverless services for our architecture.
First of all, although we didn’t mention it in the previous architectures, we need a component for handling the DNS requests so the client (browser) can request the desired web page.
With AWS, we have Amazon Route 53 as a fully managed DNS service.
For exposing our app frontend and managing the HTTP requests, will use a Content Delivery Network (CDN) component, Amazon CloudFront.
It will serve us for easy integration with the next services we will use, and will increase the page loading speed through caching.
For managing the static web content, we will use Amazon S3 connected directly to CloudFront. It is a low-cost, serverless, and easy-to-manage solution.
For handling authentication and authorization, we can use Amazon Cognito. It will allow us to manage our user pool and give us a serverless approach for registration, login, and updating user data, along with the possibility to integrate with third-party web identity providers like Google, Facebook and Amazon (and others).
We will use the fully managed service Amazon API Gateway that allow us to create, maintain, and secure APIs at any scale.
How can we handle the business logic in a scalable, cost-effective, and serverless way?
We could use Amazon ECS with Fargate to deploy containerized microservices.
But perhaps a better option could be using AWS Lambda functions. With lambda, we can create different endpoints for our backend needs. For the sake of simplicity, in our diagram we will show each module (microservice) as one lambda function.
For the database, we can choose between different options depending on whether we are using relational or non-relational databases.
For our e-commerce example let’s go with a non-relational approach: Amazon DynamoDB. We will assume a multi-table approach for an atomic microservice architecture.
Our finished (colorful and beautiful) architectural diagram will be as follows.
Yes, I know there may be some details not shown. Neither in the previous architecture. But please do not lose sight of our main objective: compare the three different approaches from a high-level perspective.
Advantages of Serverless architectures
- No management required: We don’t need to manage the service, only use it.
- Scalability: It scales according to the needs.
- Cost Efficiency: It is always available, although you only pay for what you use.
Challenges
- Compliance and Customization: For specific needs like compliance or custom business logic, it might not suit the requirements.
- Cost Monitoring: You need to keep an eye on charges when you have a significant amount of usage of the services, as it could cost more than a self-managed service.
What suits best or which approach is better?
There isn’t a single correct answer for this, as it will depend on the client’s needs, the size of the e-commerce platform, the team support, among many others elements to consider.
In my opinion, each approach must be used wisely and is part of a smart architectural decision made by the cloud architect.
Key takeaways
- Monolithic Architecture: It will help us to create and manage a single server with all the architecture at the expense of difficult scaling and leading to a single point of failure for our system.
- Microservices Architecture: It allow us to manage and scale independent components, serving us well for bigger and more demanding environments but creating a more complex environment to manage.
- Serverless Architecture: It reduces the management of some services but could have more limited options for customization.
So, there you have it, the advantages and disadvantages of each approach.
Now, it’s up to you to make the right decision!
Please like, subscribe, ask questions, leave your contrary opinions, and stay tuned for future posts!