Clean Architecture
An architectural approach that keeps business logic independent of frameworks, databases, and external systems.
Clean Architecture (also known as Hexagonal Architecture or Ports and Adapters) organizes code so that business logic sits at the center, independent of databases, HTTP frameworks, or any external system.
The core rule: outer layers can depend on inner layers, but never the other way around. Your domain logic doesn't import your HTTP router. Your application layer doesn't know if data comes from PostgreSQL or an in-memory store.
The number of layers can vary, but a common structure is:
- Domain contains your business rules, entities, and value objects. No external dependencies.
- Application defines use cases and the interfaces they need: repositories, external services, event publishers.
- Adapters implement those interfaces: HTTP handlers, database repositories, message publishers, third-party API clients.
When you need to swap a database, add a new API endpoint, or test your business logic without infrastructure, the architecture makes these changes straightforward. The API is an entry point to the application, not the application itself.
The trade-off is more boilerplate upfront: interfaces, adapters, and explicit wiring. For small projects, this can feel like overhead. As the system grows, it pays for itself by keeping changes isolated and business logic testable.
References
- How to implement Clean Architecture in Go (Golang) — Step-by-step guide to structuring a Go application with Clean Architecture. Covers refactoring to extract application logic, define interfaces, and separate domain from infrastructure in an idiomatic Go way.
- Combining DDD, CQRS, and Clean Architecture in Go — Shows how Clean Architecture, DDD, and CQRS complement each other in a real Go project. Covers creating a domain layer, orchestrating business logic with commands, and improving repository flexibility.
- When using Microservices or Modular Monolith in Go can be just a detail? — Demonstrates how Clean Architecture makes the choice between microservices and monolith an implementation detail. Both architectures share the same domain and application layers, differing only in interfaces and infrastructure.
- Introduction to DDD Lite: When microservices in Go are not enough — Discusses adopting DDD and Clean Architecture in Go despite community skepticism. Shows how these techniques enable teams to develop at constant velocity regardless of the codebase age.
- How to use basic CQRS in Go — Uses CQRS together with Clean Architecture and ports and adapters. Explains how separating commands and queries fits within Clean Architecture layers and when to skip the pattern for simple services.
- The Repository pattern in Go: a painless way to simplify your service logic — Covers the repository pattern as a key building block of Clean/Hexagonal Architecture. Shows practical implementations in SQL, NoSQL, and in-memory, with transactions handled cleanly across layers.
- Microservices test architecture. Can you sleep well without end-to-end tests? — Explains how Clean Architecture layers enable a practical test strategy. Commands and queries with external dependencies are easy to mock when you follow the Dependency Inversion Principle.
- Common Anti-Patterns in Go Web Applications — Discusses how many Go projects claim to follow Clean or Hexagonal Architecture but still tightly couple models across layers. Shows how separating read and write models and keeping logic independent of infrastructure avoids common pitfalls.
- The Go libraries that never failed us: 22 libraries you need to know — Recommends the go-cleanarch linter for enforcing the Dependency Inversion Rule in Clean/Hexagonal Architecture projects. Also links to DDD and Clean Architecture example repositories.
- Increasing Cohesion in Go with Generic Decorators — Shows how generic decorators help separate cross-cutting concerns from business logic, keeping Clean Architecture layers focused on a single responsibility.
- 4 practical principles of high-quality database integration tests in Go — Describes using Hexagonal Architecture to swap database implementations behind interfaces, enabling the same tests to run against different backends and quick rollback of risky changes.
- Repository secure by design: how to sleep better without fear of security vulnerabilities — Shows how Clean Architecture's separation of concerns helps abstract infrastructure details. After introducing the pattern, the team used it to abstract even rendering engines in non-web projects.
- Is Clean Architecture Overengineering? — Dedicated episode discussing whether Clean Architecture is overengineering or a best practice. Covers when the pattern makes sense, common pitfalls, and how to implement it without unnecessary complexity.
- AMA #1: Clean Architecture, Learning, Event-Driven, Go — Community Q&A episode with extensive Clean Architecture discussion. Covers when to add layers, how interfaces work in Go, and why you should start simple and evolve your architecture only when you feel the pain.
- When it's worth to write low-quality code — Discusses the tradeoff between Clean/Hexagonal Architecture and taking shortcuts. Covers when it makes sense to skip the pattern initially and how easy it is to reintroduce separation later.
- When you shouldn't use frameworks in Go — Discusses how Clean Architecture relates to framework choices in Go. References the dedicated Clean Architecture episode and recommends the pattern for larger projects expected to grow.
- Unpopular opinions about Go — Shares unpopular takes on Go, including how Clean Architecture helps organize projects pragmatically. Discusses lightweight clean architecture as a starting point even for smaller teams.
- Synchronous vs Asynchronous Architecture — Mentions Clean/Hexagonal Architecture as a pattern that makes migrating between synchronous and asynchronous communication easier by abstracting infrastructure behind interfaces.
- DDD: A Toolbox, Not a Religion — Discusses how people sometimes misapply Clean Architecture by adding too many layers. Emphasizes treating architectural patterns as tools rather than rigid rules.
- How to Know If your Software Is Overcomplicated or Oversimplified? — References Clean Architecture as an approach for managing complexity in software projects, alongside DDD and defensive programming.
- How to Create PRs That Get Merged The Same Day — Mentions Clean Architecture as a pattern that helps split features layer by layer, making pull requests smaller and easier to review.
- Event-Driven Architecture: The Hard Parts — References Clean Architecture in the context of event-driven systems, discussing how the separation argument applies even more when switching between synchronous and asynchronous patterns.
- Learning Software Skills fast: what worked for us best in the last 15 years — Mentions Clean Architecture in the context of learning software engineering skills and how hands-on practice with architectural patterns accelerates growth.