Clean Architecture

Have you ever wondered what makes a codebase good ? 🤔

I believe it's the way the code architecture facilitates the following   : 

1 . Ease of understandability

2. Ease of modifiability 


Both of these objectives can be achieved by using the principles of CLEAN ARCHITECTURE ✅

Clean Architecture

Clean Architecture: A Brief Overview

Clean Architecture is a software design philosophy introduced by Robert C. Martin (Uncle Bob) that aims to create systems that are easy to maintain, flexible to change, and scalable over time. The main idea behind Clean Architecture is to separate the core business logic from implementation details like frameworks, databases, and user interfaces. This separation ensures that changes in one part of the system (e.g., switching databases or frameworks) do not affect the core functionality, making the code more adaptable and testable.

Key Principles of Clean Architecture:

Clean Architecture Layers:

Clean Architecture is usually visualized as concentric circles, where the most critical layers (business logic) are at the center, and the outer layers (e.g., databases, frameworks) depend on the inner layers. The core structure includes:

Using Clean Architecture in a Node.js Application

Here’s how Clean Architecture can be applied to a Node.js app:

1. Entities (Core Business Logic):

These are the plain JavaScript objects or classes that represent the core of your application. In a Node.js app, this could be models representing users, products, or orders, and the fundamental rules that govern these entities.

// entities/User.js

class User {

  constructor(id, name, email) {

    this.id = id;

    this.name = name;

    this.email = email;

  }

}

module.exports = User;

2. Use Cases (Business Logic Layer):

Use cases implement the core functionality of the application. This is where your business rules live. For example, in a Node.js app, this layer could contain use cases like "createUser" or "fetchUserData."

// use-cases/CreateUser.js

module.exports = function createUser(userRepository) {

  return async function (userData) {

    const user = await userRepository.add(userData);

    return user;

  };

};


3. Interface Adapters (Controllers and Gateways):

This layer adapts between the core logic and external systems. In a Node.js app, controllers handle HTTP requests, gateways interface with databases or external APIs, and data transfer objects (DTOs) are used to move data across layers.



// controllers/UserController.js

module.exports = function userController(createUserUseCase) {

  return {

    createUser: async (req, res) => {

      const user = await createUserUseCase(req.body);

      res.status(201).json(user);

    },

  };

};


4. Frameworks and Drivers (External Libraries):

This is where frameworks like Express, database libraries (like Mongoose or Sequelize), and other external tools live. The key principle is to keep them on the outermost layer, so they don't directly affect the core business logic.


// app.js (Express framework example)

const express = require('express');

const createUser = require('./use-cases/CreateUser');

const userRepository = require('./repositories/UserRepository');

const userController = require('./controllers/UserController')(createUser(userRepository));


const app = express();

app.use(express.json());


app.post('/users', userController.createUser);


app.listen(3000, () => console.log('Server running on port 3000'));


Benefits of Clean Architecture in a Node.js App:

Conclusion

Clean Architecture is a powerful way to organize your Node.js apps for long-term maintainability. By separating concerns into layers, you can ensure that your app is both flexible and robust, making it easier to evolve as requirements change.