Introduction
Vertical Slice Architecture (VSA) is a feature-oriented architectural style that structures applications around use cases rather than technical layers. It is particularly popular in modern .NET development, often combined with tools like MediatR and minimal APIs.
This article provides an objective assessment of VSA, outlining both its strengths and its trade-offs so you can make an informed architectural decision.
What is Vertical Slice Architecture?
Vertical Slice Architecture organizes code by feature (or "slice"), where each slice contains everything required to fulfill a specific use case:
- Endpoint or controller
- Business logic
- Validation
- Data access
Example structure:
/Features
/Orders
CreateOrder.cs
GetOrder.cs
UpdateOrder.cs
Each slice is intended to be independent and self-contained.
Advantages of Vertical Slice Architecture
1. Feature-Centric Organization
Code is grouped by business capability rather than technical concern. This aligns well with how product teams think about functionality.
Benefit: Easier mapping between requirements and implementation.
2. Reduced Layer Coupling
Traditional layered architectures (Controller β Service β Repository) introduce indirection. VSA reduces or eliminates these layers.
Example using a minimal API in .NET 10:
app.MapPost("/orders", async (CreateOrderRequest request, AppDbContext db) =>
{
var order = new Order
{
CustomerId = request.CustomerId,
Total = request.Items.Sum(i => i.Price)
};
db.Orders.Add(order);
await db.SaveChangesAsync();
return Results.Created($"/orders/{order.Id}", order);
});
Benefit: Less boilerplate and fewer abstractions.
3. Improved Feature Isolation
Each slice can evolve independently, making it easier to modify or remove features.
Benefit: Lower risk when changing isolated functionality.
4. Faster Development for Small Systems
For small to medium-sized applications, VSA enables rapid development due to its simplicity.
Benefit: High velocity in early stages of a project.
Disadvantages of Vertical Slice Architecture
1. Risk of Code Duplication
Because slices are self-contained, shared logic is often duplicated instead of abstracted.
// CreateOrder slice
public static class CreateOrderValidator
{
public static bool Validate(Order order) => order.Total > 0;
}
// UpdateOrder slice
public static class UpdateOrderValidator
{
public static bool Validate(Order order) => order.Total > 0;
}
Impact:
- Increased maintenance cost
- Potential inconsistencies
2. Weak Domain Modeling
Business logic often lives in handlers or endpoints rather than domain entities.
public class Order
{
public decimal Total { get; set; }
}
Logic may instead appear in multiple slices:
if (order.Total <= 0)
{
return Results.BadRequest("Invalid order total");
}
Impact:
- Anemic domain model
- Poor encapsulation
3. Harder Cross-Cutting Concerns
Handling concerns like logging, validation, or transactions consistently can be more difficult without shared layers.
Impact:
- Repetition or reliance on middleware/pipelines
- Increased architectural complexity over time
4. Discoverability Challenges
Logic related to a single domain concept may be scattered across multiple slices.
Impact:
- Harder onboarding for new developers
- Increased cognitive load
5. Refactoring Complexity at Scale
As the system grows, duplicated logic and distributed rules make refactoring more expensive.
Impact:
- Higher risk of regressions
- Slower evolution of core business rules
When Vertical Slice Architecture Works Well
VSA is a good fit when:
- The application is small to medium in size
- Business rules are relatively simple
- Rapid development is a priority
- Teams prefer minimal abstraction
When to Be Cautious
Consider alternatives when:
- The domain is complex or evolving
- Strong domain modeling is required
- There are many shared business rules
- Long-term maintainability is critical
Practical Middle Ground
Many teams adopt a hybrid approach:
- Use vertical slices for application flow
- Extract shared domain logic into domain models
- Centralize cross-cutting concerns via middleware or pipelines
Example:
public class Order
{
public decimal Total { get; private set; }
public void AddItem(decimal price)
{
if (price <= 0)
throw new ArgumentException("Price must be positive");
Total += price;
}
}
This preserves domain integrity while maintaining feature-based organization.
Conclusion
Vertical Slice Architecture is neither inherently good nor badβit is a trade-off.
It excels in simplicity, feature alignment, and rapid development, but can introduce duplication, weaker domain models, and scaling challenges if not carefully managed.
The key is to evaluate your system's complexity, team structure, and long-term goals before adopting it as a default architectural pattern.
Top comments (0)