# README
GO Clean Architecture
I have borrowed some of the GO standard layout which will be described below in details. For more info: https://github.com/golang-standards/project-layout
Structure:
cmd: This directory contains your application's main entry points. Each subdirectory here can represent a different executable or command-line tool for your application. For example, you might have a cmd/api
directory for your API server and a cmd/cli
directory for a command-line interface.
pkg: The pkg
directory is where you place packages (Go libraries) that are designed for reuse within your project but could potentially be used by other projects in the future. These packages should be relatively self-contained and independent of your application's business logic. So pkg
is used for code that can be reused across different projects. If you have generic utilities or libraries that might be useful elsewhere, you can put them here.
internal: The internal
directory is for packages that are specific to your project and should not be imported by other projects. It's a way to enforce encapsulation and limit access to certain parts of your codebase. So this is a directory meant for code that is specific to your application and not meant to be reused.
configs: Store your configuration files here. These files might include environment-specific configuration settings, database configuration, and other application settings.
web: If your application includes web assets (HTML templates, JavaScript files, CSS stylesheets, etc.), you can organize them in this directory.
Clean Architecture:
The Clean Architecture, proposed by Robert C. Martin, focuses on separating concerns into layers with strict dependencies among them. It consists of several concentric circles, with the innermost circle representing the core business logic or domain, surrounded by layers like Use Cases, Interface Adapters, and Frameworks & Drivers. In Clean Architecture, the emphasis is on maintaining independence of the inner layers from the outer layers, allowing for easier testing, maintenance, and adaptability.
The key point in Clean Architecture is that the inner layers (use cases/entities) should not depend on the outer layers (such as frameworks, databases, or UI). Instead, the dependencies should flow from the outer layers towards the inner layers, allowing for flexibility, testability, and easier maintenance.
Some Notes: In this project i was using DI (dependency injection) container for managing and handling dependencies between various components of an application.
For logging i was using zerolog. Since service layer should not depend on any external packages, frameworks etc... i was using adapter pattern so it depends on interface.
If you want to replace zerolog with some other package you can do it, all you need to do is to implement the interface and the methods regarding that package.
Terminology: Some terminology may differ from team to team
- Domain / Model / Entity
- Use Cases / Services / Interactors
- Presenters / Controllers / Delivery
- Repository / Gateway
Clean Flow: The flow typically involves:
-
Controllers Depending on Frameworks: It's common for controllers in Clean Architecture to depend on frameworks or libraries for handling HTTP requests or other external inputs. For example using GIN for handling HTTP requests is a practical implementation detail that fits within the boundaries of the Clean Architecture. The key is to isolate these dependencies within the outer layers and prevent them from leaking into the core business logic.
-
Controllers Depending on Services/Usecases: This represents the flow where the controllers, after handling incoming requests using the framework, pass control to the services or use cases to execute the application-specific logic. This demonstrates the separation of concerns, with controllers acting as the entry point and delegating business logic to the appropriate layers.
-
Services/Usecases Depending on Models/Domain: This aligns with the Clean Architecture principle where the core business logic resides in the inner layers. Services or use cases should indeed depend on the domain models or entities, as they encapsulate the essential business rules and data structures.
-
Services/Usecases Depending on Repository Interfaces: Utilizing repository interfaces as abstractions is a core tenet of Clean Architecture. By depending on repository interfaces rather than concrete implementations, your use cases or services remain decoupled from specific data storage mechanisms or implementations. This allows for flexibility in swapping or modifying data access methods without affecting the business logic.
In Clean Architecture, there isn't a strict limit on the number of layers you can have. The primary focus of Clean Architecture is on separation of concerns and maintaining a clear, understandable, and maintainable codebase. The number of layers can vary based on the complexity and requirements of the application. Some applications might benefit from having more layers to clearly separate concerns, while others might achieve the same goals with fewer layers.
Clean vs N-Tier:
Both Clean Architecture and N-Tier Architecture aim to organize software into layers for better maintainability, separation of concerns, and scalability. They share similarities in the sense that they advocate for dividing an application into distinct layers to manage complexity and improve maintainability.
In Clean Architecture, there's a strong emphasis on Dependency Inversion Principle (DIP) and Dependency Injection. Clean Architecture advocates for the use of abstractions/interfaces (loosely coupled and testable code) to define interactions with external resources (like databases, file systems, etc.), keeping the inner layers independent of the concrete implementations of these resources.
N-Tier Architecture, on the other hand, does not specifically enforce this level of abstraction. While it also divides the application into layers (presentation, business logic, data access), it might not inherently emphasize the use of interfaces to abstract data access.
In a traditional n-tier architecture, the flow often follows a more rigid, top-to-bottom approach, and injecting business logic into other business logic layers might not be a typical practice. The structure tends to be more hierarchical, with a clear separation between layers
In Clean Architecture, the emphasis on creating clean abstractions allows for greater flexibility in dependency management. Clean Architecture's focus on abstractions and independence between layers encourages and supports injecting abstractions, including business logic, into other components. It is not uncommon in clean architecture to inject busness into business layer but it should be done thoughtfully maintaining the clarity and separation of concerns.
Clean Diagrams: