DEV Community

Jairo Blanco
Jairo Blanco

Posted on

REPR vs MVC: A Pragmatic Comparison

Introduction

When building web applications in .NET, most developers default to MVC (Model-View-Controller). It’s familiar, well-documented, and deeply integrated into ASP.NET Core.

However, modern API design has shifted toward feature-oriented architectures, where REPR (Request-Endpoint-Response) is gaining traction—especially with libraries like FastEndpoints.

This article provides a deeper, production-oriented comparison, including architectural implications, scalability, testing, and alignment with patterns like CQRS.


What is MVC?

MVC separates concerns into three components:

  • Model → Domain/data + business logic
  • View → UI rendering (Razor, HTML, etc.)
  • Controller → Handles HTTP requests and orchestrates responses

Example

[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
    private readonly IUserService _service;

    public UsersController(IUserService service)
    {
        _service = service;
    }

    [HttpGet("{id}")]
    public IActionResult GetUser(int id)
    {
        var user = _service.GetUserById(id);

        if (user is null)
            return NotFound();

        return Ok(user);
    }

    [HttpPost]
    public IActionResult CreateUser(CreateUserDto dto)
    {
        var user = _service.Create(dto);
        return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user);
    }
}
Enter fullscreen mode Exit fullscreen mode

Observations

  • Multiple endpoints per controller
  • Shared dependencies across actions
  • Implicit grouping by resource (UsersController)
  • Controllers tend to grow over time (controller bloat)

What is REPR?

REPR stands for:

  • Request → Input DTO
  • Endpoint → Single use-case handler
  • Response → Output DTO

Each HTTP endpoint is implemented as a self-contained unit, typically one class per use-case.

This aligns closely with:

  • Vertical Slice Architecture
  • CQRS (Command Query Responsibility Segregation)

REPR with FastEndpoints

FastEndpoints is a .NET library that implements REPR cleanly with minimal boilerplate.

Example

public class GetUserRequest
{
    public int Id { get; set; }
}

public class GetUserResponse
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class GetUserEndpoint : Endpoint<GetUserRequest, GetUserResponse>
{
    private readonly IUserService _service;

    public GetUserEndpoint(IUserService service)
    {
        _service = service;
    }

    public override void Configure()
    {
        Get("/api/users/{id}");
        AllowAnonymous();
    }

    public override async Task HandleAsync(GetUserRequest req, CancellationToken ct)
    {
        var user = await _service.GetUserByIdAsync(req.Id);

        if (user is null)
        {
            await SendNotFoundAsync(ct);
            return;
        }

        await SendAsync(new GetUserResponse
        {
            Id = user.Id,
            Name = user.Name
        }, cancellation: ct);
    }
}
Enter fullscreen mode Exit fullscreen mode

Architectural Comparison

1. Organization

Concern MVC REPR
Structure Horizontal (controllers) Vertical (features)
Grouping By resource By use-case
Files Fewer, larger More, smaller

Key Insight:

REPR follows "screaming architecture" — your folder structure reflects business capabilities.


2. Coupling & Cohesion

  • MVC

    • High intra-controller coupling
    • Shared dependencies across unrelated actions
    • Risk of unintended side effects
  • REPR

    • High cohesion per endpoint
    • Minimal coupling
    • Dependencies are scoped per use-case

3. Scalability (Codebase, not infra)

  • MVC

    • Controllers grow (10–20+ actions common)
    • Navigation becomes harder
    • Merge conflicts increase in teams
  • REPR

    • Linear scalability (add new files, not modify existing ones)
    • Safer parallel development
    • Better suited for large teams

4. Testing

MVC

  • Requires controller setup
  • Often involves mocking multiple dependencies
  • Harder to isolate logic

REPR

  • Endpoint = unit of test
  • Minimal mocking
  • Highly deterministic
// Example test idea (pseudo)
var endpoint = new GetUserEndpoint(fakeService);
await endpoint.HandleAsync(request, ct);
Enter fullscreen mode Exit fullscreen mode

5. Alignment with CQRS

Pattern MVC REPR
Commands & Queries Mixed in controllers Naturally separated
Read/Write models Often shared Easily separated
Mental model Resource-centric Use-case-centric

REPR maps almost 1:1 with CQRS.


6. Performance Considerations

FastEndpoints removes some MVC overhead:

  • No controller discovery pipeline
  • Less reflection-heavy execution
  • Leaner middleware interaction

While differences are often negligible, REPR frameworks can offer slightly better throughput and lower allocations.


FastEndpoints: Key Features

  • Strongly typed request/response models
  • Built-in validation pipeline
  • Pre/post processors (middleware-like)
  • Fluent configuration
  • Minimal boilerplate
  • Endpoint-level dependency injection

Example: Validation

public class CreateUserValidator : Validator<CreateUserRequest>
{
    public CreateUserValidator()
    {
        RuleFor(x => x.Name).NotEmpty();
    }
}
Enter fullscreen mode Exit fullscreen mode

When to Use MVC

Use MVC if:

  • You are building server-rendered apps (Razor Views)
  • Your team is heavily invested in MVC
  • You are maintaining legacy systems
  • You prefer convention over explicit structure

When to Use REPR (FastEndpoints)

Use REPR if:

  • You are building APIs or microservices
  • You want feature-based organization
  • You value low coupling and high cohesion
  • You are adopting CQRS or Vertical Slice Architecture
  • You want better team scalability

Trade-offs

MVC Drawbacks

  • Controller bloat
  • Harder long-term maintainability
  • Implicit coupling between endpoints

REPR Drawbacks

  • Higher file count
  • Initial learning curve
  • Less "standard" in enterprise environments (for now)

Folder Structure Comparison

MVC

Controllers/
  UsersController.cs
Services/
Models/
Enter fullscreen mode Exit fullscreen mode

REPR

Features/
  Users/
    GetUser/
      Endpoint.cs
      Request.cs
      Response.cs
    CreateUser/
      Endpoint.cs
      Validator.cs
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

MVC is a proven and stable architectural pattern, but it shows its age in large, API-heavy systems.

REPR—especially with FastEndpoints—offers:

  • Better scalability
  • Clearer separation of concerns
  • Strong alignment with modern architectural patterns

If you're building a new .NET API in 2026, REPR is not just an alternative—it’s often the more maintainable default.


Further Reading

  • FastEndpoints GitHub
  • ASP.NET Core MVC docs
  • Vertical Slice Architecture (Jimmy Bogard)

Top comments (0)