Vertical Slice Architecture

Vertical Slice Architecture

5 min read··

dotnetsoftware-architecturevertical-slice-architecture

Vertical Slice Architecture organizes a system around features instead of technical layers. All the files for a single use case live in one folder. This minimizes coupling between unrelated features and maximizes coupling inside a single feature.

Stop wasting time and focus on the skills employers are actually looking for today with Julio's .NET Backend Developer Roadmap. A fully interactive guide with 110+ topics that link to the best videos or articles on the web. Get it for free here.

Acorn offers a free cloud sandbox environment where you can deploy applications with the power of Kubernetes. Learn more about Acorn.

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.

Clean Architecture mapping entities, use cases, API endpoints, and external services to their respective layers

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:

Vertical slice architecture with each feature crossing Presentation, Application, Domain, and Infrastructure layers

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.

Four activity API vertical slices using EF Core, Dapper, a rich domain model, and ExecuteDeleteAsync

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

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!


Frequently Asked Questions

What is Vertical Slice Architecture?

Vertical Slice Architecture organizes a system around features instead of technical layers. All the files for a single use case live in one folder, which minimizes coupling between unrelated features and maximizes coupling inside a single feature.

What is the difference between Vertical Slice Architecture and Clean Architecture?

Clean Architecture groups code into technical layers with pre-determined dependency directions, so one feature touches many layers. Vertical Slice Architecture groups all the code for one use case together, trading layer boundaries for high cohesion per feature.

What is the REPR pattern?

REPR stands for Request-EndPoint-Response. It structures each web API endpoint around three components: a request, the endpoint that handles it, and a response. It aligns naturally with vertical slices, and libraries like MediatR, FastEndpoints, and ApiEndpoints support it.

What are the downsides of Vertical Slice Architecture?

Because much of the business logic sits inside a single use case, a slice can grow until it does too much. You need to spot code smells and refactor by pushing logic down into the domain model.

Can each vertical slice use a different data access approach?

Yes. Slices are independent, so you can tailor each implementation to its requirements. One slice can query with EF Core while another uses Dapper with raw SQL, without affecting the rest of the system.

Loading comments...

Whenever you're ready, there are 4 ways I can help you:

  1. Pragmatic Clean Architecture: Join 5,000+ students in this comprehensive course that 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.
  2. Modular Monolith Architecture: Join 2,800+ engineers in this in-depth course that will transform the way you build modern systems. You will learn the best practices for applying the Modular Monolith architecture in a real-world scenario.
  3. Pragmatic REST APIs: Join 1,900+ students in this course that will teach you how to build production-ready REST APIs using the latest ASP.NET Core features and best practices. It includes a fully functional UI application that we'll integrate with the REST API.
  4. Patreon Community: Join a community of 5,000+ engineers and software architects. You will also unlock access to the source code I use in my YouTube videos, early access to future videos, and exclusive discounts for my courses.

The .NET Weekly

Become a Better .NET Software Engineer

Join 66,000+ engineers who are improving their skills every Saturday morning.