Skip to content

QBSCarlosClemente/dotnet-microservices-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 

Repository files navigation

🏗️ .NET Microservices Template with Docker & Clean Architecture

Template de producción para arquitectura de microservicios con .NET 8, Docker, PostgreSQL y RabbitMQ. Listo para deploy en Azure AKS o AWS EKS.

.NET Docker PostgreSQL RabbitMQ


¿Qué incluye?

Este template implementa los patrones y prácticas que uso en producción con mis clientes empresariales. No es un ejercicio académico — es la base real desde la que construyo sistemas que corren 24/7.

Arquitectura

graph TB
    subgraph "🌐 API Gateway — YARP"
        GW["Gateway<br/>Routing · Rate Limit · Auth"]
    end

    subgraph "🔧 Microservicios"
        CAT["Catalog<br/>Service"]
        ORD["Orders<br/>Service"]
        INV["Inventory<br/>Service"]
    end

    subgraph "📨 Mensajería"
        RMQ["RabbitMQ<br/>Event Bus"]
    end

    subgraph "💾 Base de Datos (1 por servicio)"
        DB1[("PostgreSQL<br/>Catalog")]
        DB2[("PostgreSQL<br/>Orders")]
        DB3[("PostgreSQL<br/>Inventory")]
    end

    GW --> CAT
    GW --> ORD
    GW --> INV

    CAT <-->|Events| RMQ
    ORD <-->|Events| RMQ
    INV <-->|Events| RMQ

    CAT --> DB1
    ORD --> DB2
    INV --> DB3

    style GW fill:#334155,stroke:#38bdf8,color:#f1f5f9
    style CAT fill:#1e3a5f,stroke:#22c55e,color:#f1f5f9
    style ORD fill:#1e3a5f,stroke:#22c55e,color:#f1f5f9
    style INV fill:#1e3a5f,stroke:#22c55e,color:#f1f5f9
    style RMQ fill:#7c3aed,stroke:#a855f7,color:#f1f5f9
    style DB1 fill:#44403c,stroke:#f97316,color:#f1f5f9
    style DB2 fill:#44403c,stroke:#f97316,color:#f1f5f9
    style DB3 fill:#44403c,stroke:#f97316,color:#f1f5f9
Loading

Clean Architecture por Servicio

graph TB
    subgraph "Cada Microservicio"
        API["🌐 API Layer<br/>Controllers, Middleware"]
        APP["⚙️ Application Layer<br/>Use Cases, DTOs, Validators"]
        DOM["💎 Domain Layer<br/>Entities, Value Objects, Events"]
        INF["🔌 Infrastructure Layer<br/>EF Core, Repos, External Services"]
    end

    API --> APP
    APP --> DOM
    INF --> DOM
    API --> INF

    style API fill:#334155,stroke:#38bdf8,color:#f1f5f9
    style APP fill:#1e3a5f,stroke:#22c55e,color:#f1f5f9
    style DOM fill:#7c3aed,stroke:#a855f7,color:#f1f5f9
    style INF fill:#44403c,stroke:#f97316,color:#f1f5f9
Loading

Estructura del Proyecto

📦 dotnet-microservices-template
├── 📂 src/
│   ├── 📂 ApiGateway/                  # YARP reverse proxy
│   ├── 📂 Services/
│   │   ├── 📂 Catalog/
│   │   │   ├── Catalog.API/            # Controllers, middleware
│   │   │   ├── Catalog.Application/    # Use cases, DTOs
│   │   │   ├── Catalog.Domain/         # Entities, value objects
│   │   │   └── Catalog.Infrastructure/ # EF Core, repos
│   │   ├── 📂 Orders/                  # Misma estructura
│   │   └── 📂 Inventory/              # Misma estructura
│   └── 📂 BuildingBlocks/
│       ├── EventBus/                   # RabbitMQ abstraction
│       ├── Common/                     # Shared kernel
│       └── Auth/                       # JWT + policy-based auth
├── 📂 tests/
├── 📂 deploy/
│   ├── docker-compose.yml
│   └── k8s/                           # Kubernetes manifests
├── 📂 docs/adr/                       # Architecture Decision Records
└── .github/workflows/                  # CI/CD

Comunicación entre Servicios

sequenceDiagram
    participant Client as 🌐 Cliente
    participant GW as ⚡ Gateway
    participant Orders as 📦 Orders Service
    participant RMQ as 📨 RabbitMQ
    participant Inv as 📋 Inventory Service

    Client->>GW: POST /api/orders
    GW->>Orders: Crear orden
    Orders->>Orders: Validar + Persistir
    Orders-->>GW: 201 Created
    GW-->>Client: Order ID

    Orders->>RMQ: Publish: OrderConfirmedEvent
    RMQ->>Inv: Consume: OrderConfirmedEvent
    Inv->>Inv: Reservar stock
    Inv->>RMQ: Publish: StockReservedEvent
Loading

Patrones Implementados

Domain Entity

public class Order : AggregateRoot
{
    public OrderId Id { get; private set; }
    public CustomerId CustomerId { get; private set; }
    public OrderStatus Status { get; private set; }
    private readonly List<OrderItem> _items = new();

    public void AddItem(ProductId productId, int quantity, decimal price)
    {
        var item = new OrderItem(productId, quantity, price);
        _items.Add(item);
        AddDomainEvent(new OrderItemAddedEvent(Id, item));
    }

    public void Confirm()
    {
        if (Status != OrderStatus.Draft)
            throw new DomainException("Only draft orders can be confirmed");
        Status = OrderStatus.Confirmed;
        AddDomainEvent(new OrderConfirmedEvent(Id));
    }
}

CQRS con MediatR

// Command
public record CreateOrderCommand(CustomerId CustomerId, List<OrderItemDto> Items) 
    : IRequest<OrderId>;

// Query  
public record GetOrderByIdQuery(OrderId Id) 
    : IRequest<OrderDetailsDto>;

Event-Driven Communication

public class OrderConfirmedEventHandler : INotificationHandler<OrderConfirmedEvent>
{
    private readonly IEventBus _eventBus;

    public async Task Handle(OrderConfirmedEvent notification, CancellationToken ct)
    {
        await _eventBus.PublishAsync(new OrderConfirmedIntegrationEvent
        {
            OrderId = notification.OrderId,
            Items = notification.Items.Select(i => new OrderItemDto
            {
                ProductId = i.ProductId,
                Quantity = i.Quantity
            })
        });
    }
}

Quick Start

# Clonar
git clone https://github.com/QBSCarlosClemente/dotnet-microservices-template.git
cd dotnet-microservices-template

# Levantar todo
docker compose up -d

# Verificar servicios
curl http://localhost:5000/health          # Gateway
curl http://localhost:5001/health          # Catalog
curl http://localhost:5002/health          # Orders
curl http://localhost:15672                # RabbitMQ Management

# Correr tests
dotnet test tests/

Principios de Diseño

  1. Database per Service — Cada servicio es dueño de sus datos
  2. Smart endpoints, dumb pipes — La lógica vive en los servicios, no en el broker
  3. Design for failure — Circuit breakers, retries, fallbacks
  4. Infrastructure as Code — Todo reproducible con docker compose up
  5. Observable by default — Health checks, structured logging, métricas

Basado en experiencia real

Este template es la destilación de patrones que uso en proyectos reales de manufactura, fintech y e-commerce. No es un tutorial — es la base desde la que arranco cada proyecto nuevo en .NET.

Autor

Carlos Clemente Olivares Senior Software Engineer · 25+ años · Especialista en arquitectura de soluciones empresariales

LinkedIn

About

Production-ready .NET 8 microservices template with Docker, Clean Architecture, CQRS, RabbitMQ and PostgreSQL

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors