Vertical Slice Architecture

Milan Jovanović - Nov 6 '23 - - Dev Community

Layered architectures are the foundation of many software systems. However, layered architectures organize the system around technical layers. And the cohesion between layers is low.

What if you wanted to organize the system around features instead?

Minimize coupling between unrelated features and maximize coupling in a single feature.

Today I want to talk about Vertical Slice Architecture, which does precisely that.

The Problem With Layered Architectures

Layered architectures organize the software system into layers or tiers. Each of the layers is typically one project in your solution. Some of the popular implementations are N-tier architecture or Clean architecture.

Layered architectures focus on separating the concerns of the various components. This makes it easier to understand and maintain the software system. And there are many benefits of structured software design,such as maintainability, flexibility, and loose coupling.

Image description

However, layered architectures also impose constraints or rigid rules on your system. The direction of dependencies between layers is pre-determined.

For example, in Clean Architecture:

  • Domain should have no dependencies
  • Application layer can reference the Domain
  • Infrastructure can reference both Application and Domain
  • Presentation can reference both Application and Domain

You end up having high coupling inside a layer and low coupling between layers. This doesn't mean layered architectures are bad. But it does mean you will have many abstractions between individual layers. And more abstractions mean increased complexity because there are more components to maintain.

What is Vertical Slice Architecture?

I first heard about Vertical Slice Architecture from Jimmy Bogard. He's also the creator of some popular open-source libraries like MediatR and Automapper.

Vertical Slice Architecture was born from the pain of working with layered architectures. They force you to make changes in many different layers to implement a feature.

Let's imagine what adding a new feature looks like in a layered architecture:

  • Updating the domain model
  • Modifying validation logic
  • Creating a use case with MediatR
  • Exposing an API endpoint from a controller

The cohesion is low because you are creating many files in different layers.

Vertical slices take a different approach:

Minimize coupling between slices, and maximize coupling in a slice.

Here's how you can visualize vertical slices:

Image description

All the files for a single use case are grouped inside one folder. So, the cohesion for a single use case is very high. This simplifies the development experience. It's easy to find all the relevant components for each feature since they are close together.

Implementing Vertical Slices

If you're building an API, the system already breaks down into commands (POST/PUT/DELETE) and queries (GET). By splitting the requests into commands and queries, you're getting the benefits of the CQRS pattern.

Vertical slices narrowly focus on a single feature. This allows you to treat each use case separately and tailor the implementation to the specific requirements. One vertical slice can use EF Core to implement a GET request. Another vertical slice can use Dapper with raw SQL queries.

Image description

Another benefit of implementing vertical slices like this is:

New features only add code, you're not changing shared code and worrying about side effects.

However, vertical slices have their own set of challenges. Because you are implementing much of the business logic inside a single use case, you need to be able to spot code smells. As the use case grows, it can end up doing too much. You will have to refactor the code by pushing logic to the domain.

Solution Structure With REPR Pattern

Layered architectures, such as Clean architecture, organize the solution across layers. This results in a folder structure grouped by technical concerns.

Vertical slice architecture, on the other hand, organizes the code around features or use cases.

An interesting approach to structuring APIs around features is using the REPR pattern.It stands for Request-EndPoint-Response. This aligns perfectly with the idea of vertical slices. You can achieve this with the MediatR library, for example.

The REPR pattern defines that web API endpoints should have three components:

  • Request
  • Endpoint
  • Response

Here's an example solution structure in .NET. You'll notice the Features folder, which contains the vertical slices. Each vertical slice implements one API request (or use case).

🔗 RunTracker.API
|__ 📁 Database
|__ 📁 Entities
    |__ #️⃣ Activity.cs
    |__ #️⃣ Workout.cs
    |__ #️⃣ ...
|__ 📁 Features
    |__ 📁 Activities
        |__ 📁 GetActivity
            |__ #️⃣ ActivityResponse.cs
            |__ #️⃣ GetActivityEndpoint.cs
            |__ #️⃣ GetActivityQuery.cs
            |__ #️⃣ GetActivityQueryHandler.cs
        |__ 📁 CreateActivity
            |__ #️⃣ CreateActivity.cs
                |__ #️⃣ CreateActivity.Command.cs
                |__ #️⃣ CreateActivity.Endpoint.cs
                |__ #️⃣ CreateActivity.Handler.cs
                |__ #️⃣ CreateActivity.Validator.cs
    |__ 📁 Workouts
    |__ 📁 ...
|__ 📁 Middleware
|__ 📄 appsettings.json
|__ 📄 appsettings.Development.json
|__ #️⃣ Program.cs
Enter fullscreen mode Exit fullscreen mode

A few more libraries for implementing the REPR pattern:

Next Steps

Some of you may not like the idea of grouping all the files related to a feature in a single folder.

However, there's a lot of value in grouping by features in general. You don't have to implement vertical slices. But you can apply this concept to your domain by grouping files around aggregates, for example. This is the approach I show in Pragmatic Clean Architecture.

I made a video about Vertical Slice Architecture, showing how to implement the concepts discussed in today's issue. Check it out here.

Thanks for reading, and stay awesome!


P.S. Whenever you're ready, there are 2 ways I can help you:

  1. Pragmatic Clean Architecture: This comprehensive course will teach you the system I use to ship production-ready applications using Clean Architecture. Learn how to apply the best practices of modern software architecture. Join 1,150+ students here.

  2. Patreon Community: Think like a senior software engineer with access to the source code I use in my YouTube videos and exclusive discounts for my courses. Join 920+ engineers here.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .