Template de producción para arquitectura de microservicios con .NET 8, Docker, PostgreSQL y RabbitMQ. Listo para deploy en Azure AKS o AWS EKS.
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.
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
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
📦 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
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
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));
}
}// Command
public record CreateOrderCommand(CustomerId CustomerId, List<OrderItemDto> Items)
: IRequest<OrderId>;
// Query
public record GetOrderByIdQuery(OrderId Id)
: IRequest<OrderDetailsDto>;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
})
});
}
}# 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/- Database per Service — Cada servicio es dueño de sus datos
- Smart endpoints, dumb pipes — La lógica vive en los servicios, no en el broker
- Design for failure — Circuit breakers, retries, fallbacks
- Infrastructure as Code — Todo reproducible con
docker compose up - Observable by default — Health checks, structured logging, métricas
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.
Carlos Clemente Olivares Senior Software Engineer · 25+ años · Especialista en arquitectura de soluciones empresariales