Blog
Apr 23, 2025 - 8 MIN READ
From Boilerplate to Production: Building My Clean Architecture .NET API Template

From Boilerplate to Production: Building My Clean Architecture .NET API Template

A practical walkthrough of my .NET Clean Architecture template, the architectural decisions behind it, and how it helps ship maintainable APIs faster.

My profile picture

Rafael García González

From Boilerplate to Production: Building My Clean Architecture .NET API Template

Creating a production-ready API should not mean starting from zero every time. In this post, I’ll walk through the design and structure of my Clean Architecture .NET API template, why I built it, and how yo can use it to have an implementation without sacrificing time and maintainability.

Why I built this template

When starting a .NET project, a lot of time is often lost in the initial setup and in installing the necessary dependencies to ensure proper functionality. This includes things like configuring the database connection, Swagger documentation, entity and service abstractions, and more.

For that reason, I decided to create this template with everything needed to quickly start developing a REST API following the principles of Clean Architecture.

What the template includes

This template brings together the core building blocks needed to start a production-ready .NET API with a clean and maintainable structure. It includes a layered architecture with clear separation of responsibilities across DomainApplicationInfrastructure, and Presentation.Api.

It also implements CQRS to organize commands and queries in a more scalable way, along with a unified result and error handling approach for consistent responses across the application. On top of that, it includes validation with FluentValidation, dependency injection through extension methods, authentication and authorization features, email sending with templates, and persistence with EF Core and PostgreSQL. In addition, it comes with dockerfile and docker compose pre-configuration, deploy-ready.

AreaWhat it includes
ArchitectureClean Architecture with clear separation into Domain, Application, Infrastructure, and Presentation.Api
CQRSCommands and Queries with handlers and sender abstractions
Result handlingUnified success, error, unauthorized, conflict, and not found responses
ValidationFluentValidation integrated into the application layer
Dependency InjectionClean wiring through extension methods like AddApi, AddApplication, AddDatabase, and AddEmailService
AuthenticationSign up, sign in, refresh token, JWT generation, and email verification
AuthorizationPolicies and permissions-based access control
UsersSearch with pagination, sorting, and get-by-id with relations
SecurityRole and policy management features
EmailSMTP email service with template rendering support
PersistenceEF Core with PostgreSQL, database initialization, and seeding
DeploymentDockerfile and Docker Compose configured for faster deployments

Project structure

Solution layout

This repository contains the following projects (high-level):

  • CleanArchTemplate.Domain
  • CleanArchTemplate.Application
  • CleanArchTemplate.Infrastructure
  • CleanArchTemplate.SharedKernel
  • CleanArchTemplate.Presentation.Api (startup project)

And the solution file:

  • CleanArchTemplate.sln

Project structure explained (where to put what)

CleanArchTemplate.Domain

What it is: The core of the system.
What goes here:

  • Entities / Aggregates
  • Value Objects
  • Domain Events
  • Domain services (pure business logic)
  • Business rules/invariants

Notes:

  • Avoid dependencies on ASP.NET Core, EF Core, or any external libraries that “talk to the outside world”.
  • This project should be the most stable over time.

CleanArchTemplate.Application

What it is: Application use-cases and orchestration.
What goes here:

  • Use cases / application services (commands/queries - CQRS)
  • Validation and business workflows that coordinate domain objects

CleanArchTemplate.Infrastructure

What it is: Implementation details and integrations.
What goes here:

  • EF Core DbContext, mappings, configurations
  • External service clients (HTTP clients, message brokers, file storage, etc.)

Notes:

  • This layer depends on Application and Domain.
  • This is where “real world” concerns live.

CleanArchTemplate.Presentation.Api (Startup Project)

What it is: The HTTP API boundary (ASP.NET Core).
What goes here:

  • Controllers
  • API configuration (DI wiring, middleware, Swagger, auth, etc.)

Notes:

  • This project is the entry point of the application and is the startup project.

CleanArchTemplate.SharedKernel

What it is: Cross-cutting/shared building blocks used across layers.

How I use it in real projects

Running the project

This repo includes a compose.yaml that starts:

  • API container (exposes port 8080)
  • PostgreSQL container (exposes port 5432)

Start:

docker compose up --build

API URL:

Database (from compose.yaml):

Note: inside Docker networking, the API uses Host=db in its connection string.

Stop:

docker compose down

Stop + remove volumes (deletes local DB data):

docker compose down -v

Option B — Run with dotnet run

Prerequisites:

  • .NET SDK installed
  • A running PostgreSQL instance (you can still use Docker only for the DB if you want)

1) Start only the database via Docker (optional but common):

docker compose up -d db

2) Run the API (startup project): From the repository root:

dotnet run --project CleanArchTemplate.Presentation.Api

The environment variables / connection strings, set them in your shell, appsettings or user secrets as appropriate.


Entity Framework Core migrations

Migrations live in Infrastructure, but they must run using the API as the startup project.

Add a migration

dotnet ef migrations add <NameOfMigration> --startup-project CleanArchTemplate.Presentation.Api --project CleanArchTemplate.Infrastructure

Apply migrations (update database)

dotnet ef database update --startup-project CleanArchTemplate.Presentation.Api --project CleanArchTemplate.Infrastructure

Typical workflow for adding a new feature

  1. Domain: create/update entities, value objects
  2. Application: add a use case (command/query), interfaces needed
  3. Infrastructure: implement persistence or integrations (EF Core, external APIs)
  4. Presentation: expose the use case via HTTP endpoint/controller and wire DI

What I would improve and add next

  • Migrate to OAuth 2.0
  • Add PDF and Excel exportation
  • Add AutoMapper
  • Add MinioService implementation
  • Add Redis implementation

Final thoughts

This template is the result of many small decisions shaped by real project needs. Over time, I realized that having a well-structured starting point makes a big difference in both speed and quality.
Rather than reinventing the same foundation on every project, I prefer to begin with something that already reflects good architectural practices and can grow with the application.

Feel free to contribute to the project

Github Repo

Built with Nuxt UI • © 2026