← Back to list

Vertical Slice Architecture in ASP .NET Web API

Introduction

Yazan Ati · 2026-06-09 19:56 · 56 claps · 2.2 min read
#vertical-slice #aspnet #aspnetcore #clean-code #csharp
Open on Medium ↗
Wiki topics: 🏛️ · Architecture

Vertical Slice Architecture in ASP .NET Web API

Introduction

As software developers, we tend to organize our code into different layers (ex. UI, Application layer, Domain layer and infrastructure layer). This is to manage complexity of application and avoid code repetition.

On other hand, in vertical slice architecture philosophy, We can organize our code around features (i.e. slices). Where each slice contains all the code needed for its feature — business use case. Slices are independent of each others. Coupling is low between slices but high in a single slice.

How is it structured and work?

Lets imagine we are building a web API to manage products. That would include the following:

1- Create a product.

2- Get a product.

Each one of these 2 points above represents a feature (business case). So, according to the vertical slice architecture philosophy, we should write the code of each feature, in one singles file that includes everything in order to make this feature works.

An example of the folders feature structure would look like this below:

Features/ Products/ CreateProduct.cs ← entire feature in one file GetProduct.cs ← entire feature in one file

Again! each file of these should include all the code for its business use case. Take a look at the below example of “CreateProduct.cs”

namespace Api.Features.Products;

public static class CreateProduct
{
    // Request
    public record Command(string Name, decimal Price) : IRequest<Response>;

    // Response
    public record Response(Guid Id, string Name, decimal Price);

    // Validation (FluentValidation)
    public class Validator : AbstractValidator<Command>
    {
        public Validator()
        {
            RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
            RuleFor(x => x.Price).GreaterThan(0);
        }
    }

    // Handler — data access lives here, no repository layer
    public class Handler(AppDbContext db) : IRequestHandler<Command, Response>
    {
        public async Task<Response> Handle(Command cmd, CancellationToken ct)
        {
            var product = new Product { Id = Guid.NewGuid(), Name = cmd.Name, Price = cmd.Price };
            db.Products.Add(product);
            await db.SaveChangesAsync(ct);
            return new Response(product.Id, product.Name, product.Price);
        }
    }

    // Endpoint
    public static void MapEndpoint(IEndpointRouteBuilder app) =>
        app.MapPost("/products", async (Command cmd, ISender sender) =>
        {
            var result = await sender.Send(cmd);
            return Results.Created($"/products/{result.Id}", result);
        });
}

As you may have noticed, the file includes an API endpoint, Command, Validator and a handler for business logic (I am using MdeitR library for CQRS).

This slice is for creating a new product. Another example for reading product will look very similar but with MediatR command replace by a query.

namespace Api.Features.Products;

public static class GetProduct
{
    public record Query(Guid Id) : IRequest<Response?>;
    public record Response(Guid Id, string Name, decimal Price);

    public class Handler(AppDbContext db) : IRequestHandler<Query, Response?>
    {
        public async Task<Response?> Handle(Query q, CancellationToken ct) =>
            await db.Products
                .Where(p => p.Id == q.Id)
                .Select(p => new Response(p.Id, p.Name, p.Price))
                .FirstOrDefaultAsync(ct);
    }

    public static void MapEndpoint(IEndpointRouteBuilder app) =>
        app.MapGet("/products/{id:guid}", async (Guid id, ISender sender) =>
            await sender.Send(new Query(id)) is { } r ? Results.Ok(r) : Results.NotFound());
}

When to use vertical slice architecture?

  • CRUD-heavy or feature-driven apps (APIs, internal tools) where features evolve independently
  • Teams that want to add features without understanding the whole system
  • When most changes are “add a new endpoint” rather than “change a core domain rule”

When NOT to use it?

rich shared domain logic with complex invariants or small apps that would work without an architecture.

BIG Thanks for Reading !!!!!


메타데이터
post_id
0fe3fde247ea
slug
vertical-slice-architecture-in-asp-net-web-api-0fe3fde247ea
url
https://medium.com/@yazanati-s1/vertical-slice-architecture-in-asp-net-web-api-0fe3fde247ea
canonical_url
https://medium.com/@yazanati-s1/vertical-slice-architecture-in-asp-net-web-api-0fe3fde247ea
author_url
https://medium.com/@yazanati-s1
status
ok
fetched_at
2026-07-10 03:40:03