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