Onion Architecture. Why Your Codebase Deserves Some Layers

3 min read

Image
Tired of spaghetti code? Let's talk about Onion Architecture, a layered approach to software design that keeps your core logic clean and your dependencies in check.

Ever had one of those “just one small change” moments that ended in an avalanche of broken code? Yeah, me too. Once, I tried tweaking a tiny validation rule in a legacy system, only to find myself knee-deep in database queries, UI bugs, and business logic spaghetti. It was a nightmare. That’s when I realized: we needed Onion Architecture.

What’s the Deal with Onion Architecture?

Think of a well-structured codebase like an onion (minus the tears). Layers. Encapsulation. A clear separation of concerns. Onion Architecture, popularized by Jeffrey Palermo, is all about keeping your business logic independent of external dependencies.

The Layers (Peeling It Back)

  1. Core (Domain Model) – This is the heart of the application. It contains entities, value objects, and domain rules.

    • No database code, no frameworks - just pure business logic.
    • Example: In a rental platform, this layer would define Property, Reservation, and Rentier as entities, along with the business rules that govern them.
  2. Application Services (Use Cases) – This layer coordinates use cases and ensures business logic is executed properly.

    • It doesn’t implement business rules but calls them when necessary.
    • Example: A ReservationService ensures a property is available before allowing a booking.
  3. Adapters (Infrastructure & UI) – These are gateways to the outside world.

    • Databases, APIs, file systems, messaging systems, they all interact through this layer.
    • Example: A repository pattern implementation that fetches Reservations from a database.
  4. External Dependencies – The farthest layer. Things you don’t own, like ORMs, web frameworks, and third-party services.

    • These should be interchangeable without affecting business logic.
    • Example: Today, you might use PostgreSQL, but tomorrow you might switch to MongoDB without breaking core logic.

Each layer depends inward, never outward. The core doesn’t know about the database; it just defines the rules.

Why Bother?

1. Flexibility & Testability

Ever tried testing a function that’s tightly coupled to a database? Painful. With Onion, you can test business logic without worrying about infrastructure. No more “let’s just mock half the world to test this one thing.”

2. Better Code Longevity

Frameworks come and go. Today’s cutting-edge ORM might be tomorrow’s outdated relic. By keeping core logic independent, you can swap out tools without rewriting everything.

3. Scalability & Maintainability

When code is well-structured, teams can add features without breaking everything.

4. No More Accidental Spaghetti

It forces discipline. No more “just this once” shortcuts where you access the database directly from the UI.

But… Is It Worth It?

Not every project needs a full-on onion. If you’re building a small CRUD app, a simple layered approach might be enough. But if you’re dealing with complex business rules, long-term maintainability, or ever-changing tech stacks — this is a lifesaver.

Final Thoughts

Onion Architecture isn’t just about structure; it’s about mindset. Keeping dependencies at bay. Writing code that lasts. And avoiding those “just one small change” disasters. So next time you’re structuring an application, ask yourself: Does this change make my core more independent? Or am I baking in unnecessary dependencies?

Your future self (and your teammates) will thank you.