Este proyecto es un ejemplo sencillo con dos APIs hechas en .NET 9:
- InventoryService: maneja productos.
- OrderService: maneja órdenes de compra.
- Shared: clases compartidas (DTOs y una interfaz de repositorio).
Todo está en memoria (no base de datos). Sirve para aprender cosas básicas y algunas ideas de patrones.
EasyShop.sln
InventoryService/
OrderService/
Shared/
Permite crear, listar, actualizar, borrar productos y también cambiar su estado o descontar stock. Solo se usa el código del producto (el Id interno no se muestra al usuario).
Permite crear órdenes con una lista de productos. Valida que exista stock antes. Si pones el mismo código varias veces se suma la cantidad. También aplica un pequeño descuento según el tipo de cliente (regular o vip) y controla los cambios de estado de la orden.
| Verbo | Ruta | Qué hace |
|---|---|---|
| GET | /api/producto | Lista productos |
| GET | /api/producto/codigo/{codigo} | Trae uno |
| POST | /api/producto | Crea producto nuevo |
| PUT | /api/producto/codigo/{codigo} | Actualiza por código |
| DELETE | /api/producto/codigo/{codigo} | Elimina |
| PATCH | /api/producto/codigo/{codigo}/estado | Cambia estado |
| PATCH | /api/producto/{codigo}/descontar-stock?cantidad=N | Descuenta stock |
| Verbo | Ruta | Qué hace |
|---|---|---|
| POST | /api/order | Crea una orden |
| GET | /api/order/{id} | Obtiene una orden |
| GET | /api/order?estado=&canal= | Lista filtrando opcional |
| PATCH | /api/order/{id}/estado | Cambia estado |
{
"cliente": "Juan Pérez",
"canal": "web",
"tipoCliente": "vip",
"productos": [
{ "codigo": "P-100", "cantidad": 2, "precioUnitario": 25.50 },
{ "codigo": "P-100", "cantidad": 1, "precioUnitario": 25.50 },
{ "codigo": "P-200", "cantidad": 3, "precioUnitario": 10 }
]
}Los dos P-100 se combinan y queda cantidad 3.
Si el tipo de cliente es vip aplica un porcentaje mayor que si es regular. El cálculo se hace antes de guardar la orden.
Estados usados: pendiente, procesada, completada, cancelada.
Reglas simples de cambio (no se puede volver atrás ni cambiar después de completada/cancelada).
Si mandas el header:
Idempotency-Key: algun-valor-unico
La segunda vez con el mismo valor devuelve 409 (conflicto). Solo funciona mientras la app está viva (memoria).
- Repository: clases que guardan datos en listas (sin base de datos).
- Strategy: para cambiar el cálculo de descuento según el tipo de cliente.
- Factory: crea una orden especial según el canal (web / store).
- Observer: al crear la orden muestra un mensaje en consola.
- Validaciones: se usan atributos (
[Required], etc.). - Logging: se registran algunos eventos (creación, errores básicos).
dotnet build .\EasyShop.sln
dotnet run --project .\InventoryService\InventoryService.csproj
# En otra consola
dotnet run --project .\OrderService\OrderService.csprojLuego abrir los navegadores con Swagger (puertos pueden variar por tu configuración):
- Inventory: http://localhost:5106/swagger
- Order: http://localhost:5232/swagger
- 400: Datos faltantes o inválidos.
- 409: Código de producto repetido, precios distintos para un mismo código en la orden, reutilizaste Idempotency-Key, o cambio de estado no permitido.
- 404: No se encontró el recurso.
- No hay base de datos (todo se pierde al reiniciar).
- Sin pruebas automáticas todavía.
- Idempotencia sin expiración.
- No hay autenticación.
- Falta paginación en listados.
- Falta resiliencia (reintentos) en llamadas HTTP al inventario.
- Agregar base de datos real.
- Tests unitarios.
- Poner JWT para seguridad.
- Mejorar manejo de errores y respuestas uniformes.
- Reintentos cuando falla llamada al inventario.
- Otros
- Autor: Andy Agurto Urcia.
- Empresa Propia: AU DEVELOPERS.
- Correo: devopsolutionsa@gmail.com. , druagurto@hotmail.com
- Licencia: Propietario, uso interno.