Designing Layered Architecture for E-Commerce Applications
Written on
In this guide, we will explore the process of creating E-Commerce Applications utilizing Layered Architecture through a systematic approach.
Crafting an E-Commerce application with a Layered architecture can be quite intricate. We will methodically iterate through the architectural design based on specific requirements. Before we embark on this design journey, it’s essential to reflect on: What tools do we possess in our design toolkit?
I have recently launched a new course — Design Microservices Architecture with Patterns & Principles.
Architecture Design Process
Our design process will always initiate with identifying the Business Problem that informs our architectural decisions.
Subsequently, we will delve into Architecture Design Patterns and Principles pertinent to Layered Architectures, as detailed in the articles below:
- Layered (N-Layer) Architecture with SOLID Design Principles
- Software Architecture Principles: KISS, YAGNI, DRY
- Software Architecture Design Principles: SoC, SOLID
Now, according to the architecture design process outlined above, we have reached the design phase. Before we proceed, we should consider:
- What tools do we have in our design toolbox? What knowledge have we acquired so far?
This implies that every time we design our architecture, we should start by documenting Functional Requirements (FRs) and Non-Functional Requirements (NFRs). It’s also beneficial to outline any constraints or limitations of the project, such as budget and timeline.
Architecture Design Toolkit
Here’s an overview of the Architecture Design Toolkit we will utilize throughout this article while designing our E-Commerce application:
Functional Requirements — FRs
We will design a straightforward E-Commerce application, necessitating the documentation of business cases, i.e., the Functional Requirements:
- Display products
- Filter products by brand and category
- Add products to the shopping cart
- Apply discounts with coupons and calculate the total cost for items in the shopping cart
- Complete the checkout process and generate an order
- View order history and previous purchases
Non-Functional Requirements — N-FRs
After defining the requirements, as Software Architects, we must also take into account Non-Functional Requirements. Since this is our initial iteration of the E-Commerce application, we are not focusing on extreme scalability or handling a vast number of requests. Instead, we will start small and basic, which leads us to consider:
- Availability
- A limited number of concurrent users to be supported in the first design phase
- Maintainability
This section emphasizes the importance of Maintainability, ensuring that project code is organized correctly.
Architectural Styles
Having grasped both the Functional and Non-Functional Requirements, we can now assess our Design Toolkit, which encompasses the architectures, patterns, principles, and best practices we have learned and will implement in our project. While we will primarily utilize the Monolithic architecture style, we will also implement Layered (N-Layer) architecture in our design.
It’s crucial to note that Layered Architecture still adheres to the Monolithic architecture from a server design perspective, categorizing Layered Architecture as a sub-style of Monolithic architecture.
Given that we will maintain a substantial application server, we will not decompose the servers at this stage. Instead, we will delineate logical layers within our one large application server to enhance project organization.
Patterns & Principles
Incorporating principles into our design is essential for continual remembrance. If we expand our Patterns & Principles, we identify the following:
- DRY
- KISS
- YAGNI
Additionally, we have included the following principles for this chapter:
- SoC — Separation of Concerns
- SOLID
We will take these principles into account when designing our architecture. For now, we have collected these elements in our design toolkit. As we progress through this course, we will explore new architectures, patterns, and principles.
With our design toolkit established, let’s proceed to create the initial version of our E-Commerce application utilizing Layered architecture.
Design: Steps for Layered Monolithic Architecture
Below is an outline of the evolution of our monolithic architecture. Initially, we will start with a basic architecture, featuring just one application server that manages all business logic. Subsequently, we will isolate the client application and continue implementing layered architecture by separating logical layers for UI, Business Logic, and Data Access. We can also introduce additional logical layers, such as a Domain layer, and further separate Application and Business layers.
Designing Layered Architecture — E-Commerce App
Here is the final architecture design for our E-Commerce application, which applies Layered architecture.
Let’s clarify the flow of requests in our architecture:
- The client sends a request from the web, which is processed by our substantial monolithic application server. However, our project is organized according to layered architecture, ensuring that each layer addresses its responsibilities and performs database operations to persist data in a relational database.
At this point, this architecture serves us well, as it meets our requirements outlined in the FRs and NFRs, eliminating the need for a more complex design.
Adapting Technology Stack — E-Commerce App — Layered Architecture
We will implement the appropriate technology choices. As mentioned, our architecture is designed using Layered Architecture and the principles of SOLID and SoC.
Refer to the image titled “Way of Learning — The Design Flow” from our articles: Following this flow, it is now time to adapt our technology choices.
In this phase, we will apply software tools, application frameworks, and databases to our current design. I have created two distinct technology stacks: one for Java and another for Microsoft .Net ecosystems.
In the Java Technology stack, I have integrated Tomcat Web Server for deploying our monolithic application. We will develop our application using Java Enterprise Edition, resulting in a single large JAR or WAR file for deployment to our Tomcat web server. Database operations will be performed using a relational database like MySQL, PostgreSQL, or Oracle.
For the Microsoft .Net ecosystem, the tools differ slightly: we will utilize IIS as the web server for .Net applications, with ASP.Net as the application framework for developing our layered architecture, and SQL Server for relational database CRUD operations.
Thus, we have designed and adapted a technology stack for our E-Commerce application.
DEMO: Layered Monolithic Architecture Code Review — E-Commerce App
We will conduct a code review of an E-Commerce application implemented within the .NET ecosystem using ASP.Net and SQL Server for relational databases. This is an ASP.Net E-Commerce web application that I developed some time ago, but it remains relevant to our discussion.
Here are two GitHub links for your reference. The first link leads to the GitHub repository page: Code Review of ASP.Net E-Commerce Web Application:
- https://github.com/aspnetrun/run-aspnetcore-basics
- https://github1s.com/aspnetrun/run-aspnetcore-basics
Please visit the links and review the Readme file. The second link allows you to open the repository as a project folder view. This project serves as an implementation of the aspnetrun-basic template for a real-world E-Commerce web application, demonstrating features such as product listing, cart addition, checkout, and more.
This project aims to provide a swift implementation of modern web applications using the latest ASP.NET Core and EF Core technologies. This underscores why monolithic architecture remains relevant in the software industry. Layers include:
- Data Folder: Contains the Entity Framework Core Context and tables. New entities should be added to the context and properly configured. The Infrastructure project relies on Microsoft.EntityFrameworkCore.SqlServer and related EF.Core NuGet packages, which can be found in the Infrastructure layer. If you wish to modify your data access layer, it can easily be swapped with a lighter ORM like Dapper.
- Repository Folder: Implements core interfaces using Entity Framework Core and other dependencies. Most external resource dependencies for your application should be implemented in classes defined within the Infrastructure project, which must implement interfaces defined in Core. For larger projects with numerous dependencies, multiple Infrastructure projects may be beneficial (e.g., Infrastructure.Data), but typically, a single Infrastructure project containing folders suffices.
- Pages UI Folder: Implements the UI logic. Interfaces drive business requirements and implementations within this layer. The main starting point for the application is the ASP.NET Core web project, which is essentially a console application featuring a public static void Main method in Program.cs.
Evaluating: Layered Monolithic Architecture
If we evaluate the current Layered Architecture for the E-Commerce Application, we can discern the Benefits and Drawbacks listed below:
This indicates that despite the separation of logical layers, there are several drawbacks.
Problem: High Coupling Between Layers
We will now identify Problems associated with the current Layered Architecture of the E-Commerce Application. During this problem identification phase, we should ask:
- What issues exist within this current architecture?
- How can we enhance the current design as the project advances?
Below are some identified problems and potential solutions related to the current design:
From the design image, it’s evident that the UI is directly dependent on the Business layer, and the Business Layer is dependent on the Data Access Layer. We need to break these dependencies and organize the code to ensure loosely coupled services, thereby enhancing the flexibility of our codebase and accommodating shifts between different frameworks. The proposed solutions include:
- Clean Architecture
- The Dependency Rule
Designing Microservice Architecture — E-Commerce App
If we were to design the E-Commerce application using Microservice architecture, the representation would appear as follows:
Each microservice can utilize a different database type as needed; for instance, the product microservice may employ a NoSQL document database, the shopping cart microservice could use a NoSQL key-value pair database, and the order microservice might rely on a relational database according to its data storage requirements.
What’s Next?
- Clean Architecture Design with Dependency Rule
- Macro-services to Nano-services: Evolution of Software Architecture
- Microservices Architecture: Problems and Solutions with Patterns and Principles
Step by Step Design Architectures with Course
I have just released a new course — Design Microservices Architecture with Patterns & Principles.
In this course, we will explore how to design Microservices Architecture utilizing Design Patterns, Principles, and Best Practices. We will begin with designing Monolithic to Event-Driven Microservices step by step, employing the appropriate architecture design patterns and techniques.