Microservicios con
.NET 8

Tu guía completa desde cero
para construir aplicaciones modernas y escalables

Para Principiantes 45 min de lectura Ejemplos prácticos

Por Pedro Lopez
Head Teams Wirbi
Simplificando la arquitectura cloud-native

Fundamentos

¿Qué son los Microservicios?

Entendiendo el concepto desde cero

📚 Definición Simple

Imagina que tu aplicación es como un restaurante grande. En lugar de tener una sola cocina gigante donde se prepara todo (monolito), los microservicios son como tener múltiples estaciones especializadas: una para pizzas, otra para ensaladas, otra para postres. Cada una funciona independientemente pero trabajan juntas para servir al cliente.

🏗️ Monolito
Una sola aplicación grande que hace todo. Como un edificio de un solo bloque.

Ejemplo: Facebook original era un monolito PHP.
🧩 Microservicio
Pequeña aplicación que hace una sola cosa muy bien. Como una pieza de rompecabezas.

Ejemplo: Servicio solo para login de usuarios.
🔗 API
La forma en que los servicios hablan entre sí. Como un menú en un restaurante.

Ejemplo: GET /api/productos

🎯 Analogía del Día a Día

Aplicación Monolítica = Como vivir en una casa donde todo está en un solo cuarto grande
Microservicios = Como vivir en una casa con habitaciones separadas (cocina, dormitorio, baño)

Si se daña el baño, no afecta la cocina. Si quieres renovar el dormitorio, no necesitas tocar el resto de la casa.

Comparación

Monolito vs Microservicios

¿Cuándo usar cada uno? Guía práctica

Aspecto 🏗️ Monolito 🧩 Microservicios
Complejidad Inicial ✅ Simple de empezar ❌ Más complejo al inicio
Deployment ✅ Un solo paquete ❌ Múltiples servicios
Escalabilidad ❌ Escala todo junto ✅ Escala solo lo necesario
Equipos ❌ Todos trabajan en lo mismo ✅ Equipos independientes
Tecnología ❌ Una sola tecnología ✅ Múltiples tecnologías
Fallos ❌ Un error afecta todo ✅ Fallos aislados

✅ Empieza con Monolito si:

  • Tu equipo tiene menos de 10 personas
  • Estás creando un MVP o prueba de concepto
  • Tu aplicación es simple (CRUD básico)
  • No tienes experiencia con DevOps
  • El negocio aún no está claro

🚀 Migra a Microservicios cuando:

  • Tienes múltiples equipos trabajando
  • Diferentes partes escalan diferente
  • Necesitas deployments independientes
  • Quieres usar diferentes tecnologías
  • Tu monolito se volvió muy grande
Práctica

Tu Primer Microservicio

Creemos algo simple paso a paso

🎯 Lo que vamos a construir

Un servicio simple de "Lista de Tareas" (TODO List). Es el "Hola Mundo" de los microservicios. Simple pero completo.

Program.cs - Nuestro primer servicio Minimal API super simple
// 1. Creamos la aplicación web
var builder = WebApplication.CreateBuilder(args);

// 2. Agregamos servicios (como ingredientes de una receta)
builder.Services.AddEndpointsApiExplorer();  // Para documentación
builder.Services.AddSwaggerGen();             // Para probar nuestra API

var app = builder.Build();

// 3. Configuramos Swagger (interfaz para probar)
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

// 4. Lista en memoria para guardar tareas (por ahora)
var tareas = new List<Tarea>();

// 5. ENDPOINTS - Las URLs de nuestro servicio

// GET: Obtener todas las tareas
app.MapGet("/api/tareas", () =>
{
    return Results.Ok(tareas);
})
.WithName("ObtenerTareas")
.WithOpenApi();

// GET: Obtener una tarea por ID
app.MapGet("/api/tareas/{id}", (int id) =>
{
    var tarea = tareas.FirstOrDefault(t => t.Id == id);
    return tarea is null 
        ? Results.NotFound($"Tarea {id} no encontrada") 
        : Results.Ok(tarea);
})
.WithName("ObtenerTareaPorId")
.WithOpenApi();

// POST: Crear nueva tarea
app.MapPost("/api/tareas", (Tarea nuevaTarea) =>
{
    nuevaTarea.Id = tareas.Count + 1;
    nuevaTarea.FechaCreacion = DateTime.Now;
    tareas.Add(nuevaTarea);
    
    return Results.Created($"/api/tareas/{nuevaTarea.Id}", nuevaTarea);
})
.WithName("CrearTarea")
.WithOpenApi();

// PUT: Actualizar tarea
app.MapPut("/api/tareas/{id}", (int id, Tarea tareaActualizada) =>
{
    var tarea = tareas.FirstOrDefault(t => t.Id == id);
    if (tarea is null)
        return Results.NotFound();
    
    tarea.Titulo = tareaActualizada.Titulo;
    tarea.Completada = tareaActualizada.Completada;
    
    return Results.Ok(tarea);
})
.WithName("ActualizarTarea")
.WithOpenApi();

// DELETE: Eliminar tarea
app.MapDelete("/api/tareas/{id}", (int id) =>
{
    var tarea = tareas.FirstOrDefault(t => t.Id == id);
    if (tarea is null)
        return Results.NotFound();
    
    tareas.Remove(tarea);
    return Results.Ok($"Tarea {id} eliminada");
})
.WithName("EliminarTarea")
.WithOpenApi();

app.Run();

// 6. Nuestra clase modelo (¿qué es una tarea?)
public class Tarea
{
    public int Id { get; set; }
    public string Titulo { get; set; } = "";
    public bool Completada { get; set; }
    public DateTime FechaCreacion { get; set; }
}

🚀 Cómo ejecutar este servicio

  1. Instala .NET 8 SDK desde microsoft.com/net
  2. Crea una carpeta nueva: mkdir MiPrimerMicroservicio
  3. Entra a la carpeta: cd MiPrimerMicroservicio
  4. Crea el proyecto: dotnet new webapi -minimal
  5. Copia el código de arriba en Program.cs
  6. Ejecuta: dotnet run
  7. Abre tu navegador en: http://localhost:5000/swagger
Arquitectura

Arquitectura de Microservicios

Los componentes esenciales explicados

🏗️ Componentes Básicos

👤 Cliente (Frontend)
Web, Mobile, Desktop
Consume los servicios

↓ Solicitudes HTTP ↓

🚪 API Gateway
Puerta de entrada única
Enruta las solicitudes al servicio correcto

↓ Distribuye a servicios ↓

👤 Usuarios
Login, Registro
Perfiles
📦 Productos
Catálogo
Inventario
🛒 Órdenes
Carrito
Checkout

↓ Cada uno con su base de datos ↓

💾 BD Usuarios
PostgreSQL
💾 BD Productos
MongoDB
💾 BD Órdenes
SQL Server

💡 Principio Clave

Cada microservicio tiene su propia base de datos. Esto se llama "Database per Service". Es como si cada departamento de una empresa tuviera su propio archivo. No pueden acceder directamente al archivo de otro departamento, deben pedirlo a través de los canales oficiales (APIs).

Comunicación

¿Cómo se Comunican los Servicios?

Las 3 formas principales explicadas

📞

Síncrona (REST)

Como una llamada telefónica. Haces una pregunta y esperas la respuesta inmediata.

GET /api/usuarios/123
← Respuesta inmediata

✅ Cuándo usar: Necesitas respuesta inmediata
❌ Evitar si: La operación toma mucho tiempo

📨

Asíncrona (Mensajes)

Como enviar un email o WhatsApp. Envías el mensaje y no esperas respuesta inmediata.

Publicar: "Nuevo pedido"
← Sin esperar respuesta

✅ Cuándo usar: Procesos largos, notificaciones
❌ Evitar si: Necesitas confirmación inmediata

📢

Eventos

Como un grupo de WhatsApp. Publicas algo y todos los interesados lo reciben.

Evento: "Usuario Creado"
← Múltiples servicios escuchan

✅ Cuándo usar: Múltiples servicios necesitan saber
❌ Evitar si: Solo un servicio necesita la info

Ejemplo: Comunicación Síncrona Simple
// Servicio A llama a Servicio B
public class ProductoService
{
    private readonly HttpClient _httpClient;
    
    public async Task<decimal> ObtenerPrecioConDescuento(int productoId, int usuarioId)
    {
        // 1. Obtener información del producto (local)
        var producto = await _dbContext.Productos.FindAsync(productoId);
        
        // 2. Llamar al servicio de usuarios para obtener descuento
        var response = await _httpClient.GetAsync(
            $"http://usuario-service/api/usuarios/{usuarioId}/descuento"
        );
        
        var descuento = await response.Content.ReadFromJsonAsync<decimal>();
        
        // 3. Calcular precio final
        return producto.Precio * (1 - descuento);
    }
}

🎯 Regla de Oro

Empieza simple con REST (síncrono). Es más fácil de entender y debuggear.
Cuando tengas problemas de performance o necesites desacoplar servicios, entonces considera mensajería asíncrona.

Datos

Gestión de Datos

Por qué cada servicio tiene su propia base de datos

🗄️ Database per Service Pattern

Imagina que cada servicio es como un departamento en una empresa. Cada departamento tiene su propio archivo/armario con sus documentos. Si Ventas necesita información de RRHH, no puede ir a abrir su archivo directamente, debe pedirlo formalmente (a través de la API).

Servicio Tipo de BD ¿Por qué esta elección?
👤 Usuarios PostgreSQL (Relacional) Datos estructurados, relaciones entre tablas, transacciones ACID
📦 Catálogo MongoDB (NoSQL) Productos con atributos variables, búsquedas flexibles
🛒 Carrito Redis (Cache) Datos temporales, super rápido, expira automáticamente
📊 Analytics ClickHouse (Columnar) Grandes volúmenes de datos, consultas analíticas

⚠️ El Problema: Transacciones Distribuidas

Problema: ¿Qué pasa cuando necesitas actualizar datos en múltiples servicios?
Por ejemplo: Al crear un pedido, necesitas:

  1. Verificar el inventario (Servicio de Productos)
  2. Cobrar al cliente (Servicio de Pagos)
  3. Crear el pedido (Servicio de Órdenes)

Solución: Patrón SAGA - Como una cadena de dominós controlada.

Ejemplo Simple de SAGA
// Flujo de creación de pedido con SAGA
public class CrearPedidoSaga
{
    // Paso 1: Reservar inventario
    public async Task<bool> ReservarInventario(Pedido pedido)
    {
        try
        {
            await _inventarioService.ReservarProductos(pedido.Productos);
            return true;
        }
        catch
        {
            return false; // Si falla, se detiene aquí
        }
    }
    
    // Paso 2: Procesar pago
    public async Task<bool> ProcesarPago(Pedido pedido)
    {
        try
        {
            await _pagoService.Cobrar(pedido.Total, pedido.ClienteId);
            return true;
        }
        catch
        {
            // Si falla, compensamos: liberamos el inventario
            await _inventarioService.LiberarProductos(pedido.Productos);
            return false;
        }
    }
    
    // Paso 3: Crear pedido
    public async Task<bool> CrearPedido(Pedido pedido)
    {
        try
        {
            await _pedidoService.Crear(pedido);
            return true;
        }
        catch
        {
            // Si falla, compensamos todo
            await _pagoService.Reembolsar(pedido.Total, pedido.ClienteId);
            await _inventarioService.LiberarProductos(pedido.Productos);
            return false;
        }
    }
}
Resiliencia

Haciendo tu Sistema Resistente

Qué hacer cuando las cosas fallan (y siempre fallan)

🛡️ ¿Qué es Resiliencia?

Es la capacidad de tu sistema para recuperarse de los errores. Como un edificio antisísmico: no evita el terremoto, pero no se cae cuando ocurre. En microservicios, asumimos que algo siempre puede fallar.

🔄 Retry (Reintentos)

Si algo falla, inténtalo de nuevo. Como cuando el WiFi falla y recargas la página.

Ejemplo:
Intento 1: Falla ❌
Espera 1 seg
Intento 2: Falla ❌
Espera 2 seg
Intento 3: Éxito ✅

🚦 Circuit Breaker

Como un fusible eléctrico. Si algo falla mucho, deja de intentarlo por un tiempo.

Estados:
🟢 Cerrado: Todo normal
🟡 Abierto: Muchas fallas, no intenta
🔵 Semi-abierto: Prueba si ya funciona

⏱️ Timeout

No esperes para siempre. Como cuando pides pizza: si no llega en 30 min, cancelas.

Configuración típica:
API rápidas: 5 segundos
Procesos largos: 30 segundos
Reportes: 2 minutos
Implementación Simple con Polly
// 1. Instalar paquete: dotnet add package Polly

// 2. Configurar políticas de resiliencia
var retryPolicy = Policy
    .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .WaitAndRetryAsync(
        3,  // Reintentar 3 veces
        retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), // 2, 4, 8 segundos
        onRetry: (outcome, timespan, retryCount, context) =>
        {
            Console.WriteLine($"Reintento {retryCount} después de {timespan} segundos");
        });

// 3. Circuit Breaker: después de 3 fallas, espera 30 segundos
var circuitBreakerPolicy = Policy
    .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .CircuitBreakerAsync(
        3,  // Después de 3 fallas consecutivas
        TimeSpan.FromSeconds(30), // Espera 30 segundos antes de intentar de nuevo
        onBreak: (result, timespan) =>
        {
            Console.WriteLine($"Circuito abierto por {timespan}");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuito cerrado, funcionando normal");
        });

// 4. Combinar políticas
var resilientPolicy = Policy.WrapAsync(retryPolicy, circuitBreakerPolicy);

// 5. Usar en tu código
public async Task<Producto> ObtenerProducto(int id)
{
    return await resilientPolicy.ExecuteAsync(async () =>
    {
        var response = await _httpClient.GetAsync($"/api/productos/{id}");
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<Producto>();
    });
}
Contenedores

Docker para Principiantes

Empaquetando tu microservicio

📦 ¿Qué es Docker?

Docker es como un contenedor de envío para tu aplicación. Así como un contenedor puede llevar cualquier cosa y funcionar en cualquier barco, Docker empaqueta tu aplicación para que funcione en cualquier servidor.

Sin Docker: "En mi máquina funciona" 😅
Con Docker: "Funciona en todas partes" 🎉

Dockerfile - La receta de tu contenedor
# 1. Imagen base - Como elegir el sistema operativo
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80

# 2. Compilar la aplicación
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MiServicio.csproj", "."]
RUN dotnet restore "MiServicio.csproj"
COPY . .
RUN dotnet build "MiServicio.csproj" -c Release -o /app/build

# 3. Publicar la aplicación
FROM build AS publish
RUN dotnet publish "MiServicio.csproj" -c Release -o /app/publish

# 4. Imagen final - Solo lo necesario para ejecutar
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MiServicio.dll"]

🚀 Comandos Docker Esenciales

# Construir imagen
docker build -t mi-servicio .
# Ejecutar contenedor
docker run -p 8080:80 mi-servicio
# Ver contenedores corriendo
docker ps
# Detener contenedor
docker stop [container-id]
docker-compose.yml - Orquestando múltiples servicios
version: '3.8'

services:
  # Servicio de API
  api:
    build: ./ServicioAPI
    ports:
      - "8080:80"
    environment:
      - ConnectionStrings__DefaultConnection=Server=db;Database=MiDB;
    depends_on:
      - db
  
  # Base de datos
  db:
    image: postgres:15
    environment:
      - POSTGRES_PASSWORD=MiPassword123
      - POSTGRES_DB=MiDB
    volumes:
      - db-data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

volumes:
  db-data:
Testing

Testing de Microservicios

Cómo asegurarte de que todo funciona

🧪 La Pirámide de Testing

Imagina una pirámide: muchos tests pequeños y rápidos en la base, pocos tests grandes y lentos en la punta.

E2E

5% - Tests completos del sistema

Integration

30% - Tests de componentes juntos

Unit Tests

65% - Tests de funciones individuales

Unit Test Simple
using Xunit;

public class CalculadoraTests
{
    [Fact]
    public void Sumar_DosNumeros_RetornaResultadoCorrecto()
    {
        // Arrange (Preparar)
        var calculadora = new Calculadora();
        
        // Act (Actuar)
        var resultado = calculadora.Sumar(5, 3);
        
        // Assert (Verificar)
        Assert.Equal(8, resultado);
    }
    
    [Theory]
    [InlineData(1, 1, 2)]
    [InlineData(-1, 1, 0)]
    [InlineData(0, 0, 0)]
    public void Sumar_VariosEscenarios_RetornaResultadoCorrecto(int a, int b, int esperado)
    {
        var calculadora = new Calculadora();
        var resultado = calculadora.Sumar(a, b);
        Assert.Equal(esperado, resultado);
    }
}
Integration Test de API
public class ProductosApiTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly WebApplicationFactory<Program> _factory;
    
    public ProductosApiTests(WebApplicationFactory<Program> factory)
    {
        _factory = factory;
    }
    
    [Fact]
    public async Task ObtenerProductos_RetornaListaDeProductos()
    {
        // Arrange
        var client = _factory.CreateClient();
        
        // Act
        var response = await client.GetAsync("/api/productos");
        
        // Assert
        response.EnsureSuccessStatusCode();
        var productos = await response.Content.ReadFromJsonAsync<List<Producto>>();
        Assert.NotNull(productos);
        Assert.NotEmpty(productos);
    }
}

✅ Tips para Testing

  • Empieza con unit tests - son los más fáciles
  • Usa nombres descriptivos: Qué_Cuando_Entonces
  • Un test debe probar una sola cosa
  • Los tests deben ser independientes entre sí
  • Ejecuta tests automáticamente en cada commit
Observabilidad

Monitoreo y Logs

Cómo saber qué está pasando en tu sistema

👀 Los 3 Pilares de la Observabilidad

Como un doctor que examina a un paciente, necesitas diferentes herramientas para diagnosticar problemas:

📝 Logs
El diario de tu aplicación. Registra todo lo que pasa.

[INFO] Usuario 123 login exitoso
[ERROR] Fallo conexión BD
📊 Métricas
Los números vitales. Como el pulso y presión arterial.

CPU: 45%
Requests/sec: 1000
Errores: 0.1%
🔍 Traces
El recorrido de una petición. Como seguir un paquete de Amazon.

Gateway → Auth → Orders → DB
Total: 250ms
Logging Básico con Serilog
// 1. Instalar: dotnet add package Serilog.AspNetCore

// 2. Configurar en Program.cs
using Serilog;

// Configurar Serilog
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .WriteTo.Console()  // Logs en consola
    .WriteTo.File("logs/miapp-.txt", rollingInterval: RollingInterval.Day)  // Logs en archivo
    .CreateLogger();

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();  // Usar Serilog

// 3. Usar en tu código
app.MapPost("/api/pedidos", (Pedido pedido, ILogger<Program> logger) =>
{
    logger.LogInformation("Creando pedido para cliente {ClienteId}", pedido.ClienteId);
    
    try
    {
        // Procesar pedido
        var resultado = ProcesarPedido(pedido);
        
        logger.LogInformation("Pedido {PedidoId} creado exitosamente", resultado.Id);
        return Results.Ok(resultado);
    }
    catch (Exception ex)
    {
        logger.LogError(ex, "Error creando pedido para cliente {ClienteId}", pedido.ClienteId);
        return Results.Problem("Error procesando pedido");
    }
});

🎯 Health Checks - El Pulso de tu Servicio

// Agregar health checks
builder.Services.AddHealthChecks()
    .AddCheck("self", () => HealthCheckResult.Healthy())
    .AddSqlServer(connectionString)
    .AddRedis(redisConnection);

// Endpoint de salud
app.MapHealthChecks("/health");  // GET /health → 200 OK o 503 Unhealthy

💡 Tip Importante

No registres información sensible como contraseñas o números de tarjeta.
Usa niveles de log apropiados:
• DEBUG: Solo en desarrollo
• INFO: Eventos importantes normales
• WARNING: Algo raro pero manejable
• ERROR: Errores que necesitan atención

Migración

De Monolito a Microservicios

Estrategia paso a paso sin romper nada

🌱 Strangler Fig Pattern

Como una higuera que crece alrededor de un árbol viejo, los microservicios van reemplazando gradualmente partes del monolito hasta que eventualmente el monolito desaparece. No es necesario reescribir todo de una vez.

1

Identificar Límites

Mes 1

Encuentra las partes
independientes
(Usuarios, Pagos, etc.)

2

Primer Servicio

Mes 2-3

Extrae la parte
más simple
(ej: Notificaciones)

3

API Gateway

Mes 4

Punto de entrada
único que enruta
al lugar correcto

4

Iterar

Mes 5+

Repite el proceso
con más servicios
gradualmente

📋 Checklist de Migración

✅ Antes de empezar:
  • Tests automáticos del monolito
  • CI/CD pipeline funcionando
  • Monitoreo básico activo
  • Equipo capacitado
🎯 Primeros candidatos:
  • Servicios sin estado (stateless)
  • Pocas dependencias
  • Límites claros de negocio
  • Cambios frecuentes
Ejemplo: Facade Pattern para Migración
// Facade que decide si usar monolito o microservicio
public interface IUserService
{
    Task<User> GetUserAsync(int id);
}

public class UserServiceFacade : IUserService
{
    private readonly IConfiguration _config;
    private readonly HttpClient _httpClient;
    private readonly MonolithUserRepository _monolithRepo;
    
    public async Task<User> GetUserAsync(int id)
    {
        // Feature flag para migración gradual
        var useMicroservice = _config.GetValue<bool>("Features:UseUserMicroservice");
        
        if (useMicroservice)
        {
            // Llamar al nuevo microservicio
            var response = await _httpClient.GetAsync($"/api/users/{id}");
            return await response.Content.ReadFromJsonAsync<User>();
        }
        else
        {
            // Usar el código del monolito
            return await _monolithRepo.GetUserAsync(id);
        }
    }
}
Lecciones

Errores Comunes de Principiantes

Aprende de los errores de otros

❌ Error #1: Microservicios muy pequeños

Problema: Un servicio para cada tabla de BD
Solución: Agrupa por dominio de negocio, no por tablas

❌ Error #2: Compartir base de datos

Problema: Múltiples servicios usando la misma BD
Solución: Cada servicio su propia BD, comunicación por API

❌ Error #3: No pensar en fallos

Problema: Asumir que todo siempre funciona
Solución: Implementar retry, circuit breaker, timeouts

❌ Error #4: Olvidar el monitoreo

Problema: No saber qué está pasando en producción
Solución: Logs, métricas y traces desde el día 1

❌ Error #5: Transacciones distribuidas

Problema: Intentar hacer todo atómico entre servicios
Solución: Usar patrones como SAGA o eventual consistency

❌ Error #6: Empezar muy complejo

Problema: Kubernetes, Istio, etc desde el inicio
Solución: Empieza simple, evoluciona según necesites

🎯 Reglas de Oro

1. No necesitas microservicios desde el día 1 - Empieza con monolito
2. Un servicio = Un equipo - Si no tienes equipos, no necesitas microservicios
3. Automatiza todo - CI/CD es obligatorio, no opcional
4. Diseña para fallos - Todo puede y va a fallar
5. Mide todo - Si no lo puedes medir, no lo puedes mejorar
Recursos

Tu Camino de Aprendizaje

Qué estudiar después

📚

Básico

1-3 meses

• REST APIs
• Docker básico
• Unit testing
• Git & CI/CD

🚀

Intermedio

3-6 meses

• Mensajería (RabbitMQ)
• Patrones (SAGA, CQRS)
• Kubernetes básico
• Observabilidad

Avanzado

6-12 meses

• Service Mesh
• Event Sourcing
• gRPC
• Seguridad avanzada

🎯

Experto

1+ años

• Arquitectura
• Performance tuning
• Multi-cloud
• Domain-Driven Design

📚 Recursos Gratuitos

  • 📖 Microsoft Learn: Rutas de aprendizaje .NET
  • 🎥 YouTube: Nick Chapsas, Tim Corey
  • 💻 GitHub: dotnet/eShopOnContainers
  • 📝 Blogs: Martin Fowler, Jimmy Bogard
  • 🎮 Práctica: Kata de microservicios

🛠️ Herramientas Esenciales

  • 💻 IDE: Visual Studio / VS Code
  • 🐳 Contenedores: Docker Desktop
  • 📮 API Testing: Postman / Insomnia
  • 📊 Monitoreo: Seq (logs locales)
  • 🔄 CI/CD: GitHub Actions / Azure DevOps

💡 Mi Proyecto de Práctica

Construye un mini e-commerce con 3 servicios:
1. Servicio de Usuarios: Registro, login (JWT)
2. Servicio de Productos: CRUD de productos
3. Servicio de Órdenes: Crear pedidos

Esto te dará experiencia práctica con los conceptos principales.

¡Felicidades!
Ya sabes lo básico de Microservicios

Ahora es momento de practicar 💪

Recuerda: La mejor forma de aprender es construyendo

Tu siguiente paso:

1️⃣ Crea tu primer microservicio simple
2️⃣ Dockerízalo y ejecuta localmente
3️⃣ Agrega un segundo servicio
4️⃣ Haz que se comuniquen
5️⃣ Comparte tu progreso en LinkedIn 🚀

Pedro Lopez
Head Teams Wirbi
teams@wirbi.com | ¿Preguntas? ¡Escríbeme!

Slide 1 / 15