Why This Matters
Imagine writing an entire application in a single file: UI rendering, business rules, database queries, and error handling all tangled together. When you need to change the database, you risk breaking the UI. When you update a business rule, you accidentally corrupt a query. This is the nightmare that layered architecture solves.
By separating your system into distinct layers -- presentation, business logic, and data access -- each layer has one job and communicates through clean interfaces. This separation of concerns is one of the most important principles in software engineering. It makes your code easier to test, easier to change, and easier for teams to work on in parallel. Nearly every production web application, from a small startup to a major enterprise, uses some form of layered architecture.
Define Terms
Visual Model
The full process at a glance. Click Start tour to walk through each step.
Requests flow down through layers; responses flow back up. Each layer has a single responsibility.
Code Example
// Data Access Layer — talks to the database
class UserRepository {
constructor(db) {
this.db = db;
}
async findById(id) {
return this.db.query("SELECT * FROM users WHERE id = $1", [id]);
}
async save(user) {
return this.db.query(
"INSERT INTO users (name, email) VALUES ($1, $2)",
[user.name, user.email]
);
}
}
// Business Logic Layer — enforces rules
class UserService {
constructor(userRepo) {
this.userRepo = userRepo;
}
async getUser(id) {
const user = await this.userRepo.findById(id);
if (!user) throw new Error("User not found");
return user;
}
async createUser(data) {
if (!data.email.includes("@")) {
throw new Error("Invalid email");
}
return this.userRepo.save(data);
}
}
// Presentation Layer — handles HTTP
app.get("/api/users/:id", async (req, res) => {
try {
const user = await userService.getUser(req.params.id);
res.json(user);
} catch (err) {
res.status(404).json({ error: err.message });
}
});Interactive Experiment
Try these exercises:
- Identify the three layers in an application you use daily (e.g., a social media app). What does each layer do?
- Take the code example above and add a new business rule: users must have a name of at least 2 characters. Which layer does the validation belong in?
- Try moving database logic into the presentation layer. What problems arise when you want to add a new UI (e.g., a mobile app)?
- Add a logging layer that sits between business logic and data access. How does it improve debugging?
Quick Quiz
Coding Challenge
Build a simple layered order system. Create three functions: `validateOrder` (business layer) checks that the order has at least one item and a total greater than 0, returning {valid: true} or {valid: false, error: 'reason'}. `saveOrder` (data layer) takes a valid order and adds it to an array called `orders`, returning the order with an added `id` field (use orders.length + 1). `handleOrderRequest` (presentation layer) uses both functions: if valid, save and return {status: 201, body: savedOrder}; if invalid, return {status: 400, body: error message}.
Real-World Usage
Layered architecture is the standard in production systems:
- React + Express + PostgreSQL: The classic three-tier stack. React renders the presentation layer, Express handles business logic, and PostgreSQL stores data.
- Django: Follows the MTV (Model-Template-View) pattern, which is Django's version of MVC. Models are the data layer, templates are the presentation, and views contain logic.
- Enterprise Java (Spring Boot): Controllers handle requests, services contain business logic, and repositories manage data access.
- Microservices: Each microservice internally uses layers, even though the overall system is decomposed into separate services.