Lección 17 de 20 · Lectura y práctica
Implementar servicios de pedidos, inventario y pagos con gRPC
Concepto claveEn un sistema de microservicios, la comunicación entre servicios es fundamental. gRPC (Google Remote Procedure Call) es un framework de alto rendimiento que utiliza Protocol Buffers (protobuf) como lenguaje de.
Del concepto a la práctica
Taller de esta lección
La implementación debe tratar el recorrido como una secuencia con efectos y compensaciones. Si se reserva inventario y después falla el pago simulado, el sistema necesita liberar la reserva o dejar un estado pendiente explícito; no puede afirmar que el pedido está pagado.
Ejemplo resuelto
Stock inicial BK-7: 4
Pedido: 2 unidades
Reserva: -2 -> stock 2
Pago simulado: rechazado
Compensación: +2 -> stock 4
Estado pedido: PAGO_RECHAZADOCada transición conserva una cifra reproducible.
Usa pedidoA cantidad1/pagoaceptado y pedidoB cantidad2/pagorechazado sobre BK-7; reserva, liberación y autorización requieren idempotencia, no solo la reserva. Una compensación remota también puede fallar: registra COMPENSACION_PENDIENTE con reintento durable y no declare stock restaurado antes del acuse. El stock3 esperado corresponde al fixture sin fallos en la liberación; repetir liberar(B) debe dejarlo en3.
Pruébalo
Implementa reservar, autorizar y liberar con identificador de pedido.
Ejecuta un pago aceptado y otro rechazado.
Registra stock antes, después y tras compensación.
Error frecuente: repetir la reserva al reintentar sin una clave idempotente. Corrección: usa el identificador del pedido para reconocer una operación ya aplicada.
Comprueba tu resultado
Ejercicio: parte de 4 unidades y ejecuta un pedido aceptado de 1 y uno rechazado de 2. Resultado esperado: stock final 3; el aceptado queda confirmado y el rechazado devuelve sus 2 unidades.

Mapa de prácticaUna condición decide qué camino ejecuta el programa. Un bucle repite una operación mientras queden elementos, y termina cuando la lista se agota. Separar ambas ideas ayuda a seguir el flujo y comprobar casos límite.
Ver la infografía en tamaño completo ↗Concepto clave
En un sistema de microservicios, la comunicación entre servicios es fundamental. gRPC (Google Remote Procedure Call) es un framework de alto rendimiento que utiliza Protocol Buffers (protobuf) como lenguaje de definición de interfaz y formato de serialización. A diferencia de REST/JSON, gRPC es binario, tipado y utiliza HTTP/2, lo que permite comunicación bidireccional, streaming y menor latencia.
Imagina que los microservicios son departamentos en una empresa: Ventas (pedidos), Almacén (inventario) y Contabilidad (pagos). En lugar de enviar emails (REST/JSON) con documentos largos y sin estructura, usan formularios estandarizados (protobuf) y reuniones rápidas por videollamada (gRPC) donde cada campo tiene un tipo específico y las respuestas son inmediatas. Esto elimina malentendidos y acelera los procesos.
Para nuestro proyecto integrador, implementaremos tres servicios: Pedidos (crea y gestiona órdenes), Inventario (verifica y actualiza stock) y Pagos (procesa transacciones). Cada servicio tendrá su propia definición en protobuf, generará código en el lenguaje de programación (ej. Go, Python) y se comunicará mediante llamadas gRPC sincrónicas o asíncronas según la necesidad.
Cómo funciona en la práctica
Vamos a desglosar la implementación paso a paso para un flujo típico: crear un pedido.
- Definir protobuf: Creamos archivos .proto para cada servicio. Ejemplo para servicio de pedidos:
syntax = "proto3"; package ecommerce; service OrderService { rpc CreateOrder(CreateOrderRequest) returns (OrderResponse); rpc GetOrder(GetOrderRequest) returns (OrderResponse); } message CreateOrderRequest { string user_id = 1; repeated OrderItem items = 2; float total_amount = 3; } message OrderItem { string product_id = 1; int32 quantity = 2; float price = 3; } message OrderResponse { string order_id = 1; string status = 2; // e.g., "pending", "completed", "failed" string message = 3; } - Generar código: Usamos el compilador protoc para generar código cliente y servidor. Ejemplo en Go:
protoc --go_out=. --go-grpc_out=. order.proto. Esto crea structs y interfaces listas para implementar. - Implementar servidor gRPC: En el servicio de pedidos, implementamos la lógica de negocio. Cuando se recibe CreateOrder, validamos los datos, llamamos al servicio de inventario (vía gRPC) para verificar stock, y si hay disponibilidad, llamamos al servicio de pagos para procesar el pago.
- Configurar comunicación: Usamos balanceo de carga, timeouts y retries. En Kubernetes, exponemos los servicios mediante ClusterIP y usamos service discovery.
Una tabla de comparación entre llamadas gRPC y REST para este caso:
| Aspecto | gRPC | REST/JSON |
|---|---|---|
| Formato | Binario (protobuf) | Texto (JSON) |
| Tipado | Fuerte, definido en .proto | Débil, depende de validación |
| Performance | Alta (menos overhead) | Moderada |
| Streaming | Soporte nativo (HTTP/2) | Limitado |
Caso de estudio
Consideremos una plataforma de e-commerce como Amazon. Cuando un usuario hace un pedido, el sistema debe:
- Servicio de Pedidos: Recibe la solicitud, valida los items y crea una orden en estado "pendiente".
- Servicio de Inventario: Verifica el stock para cada producto. Si algún item no tiene stock suficiente, responde con error y el pedido se cancela.
- Servicio de Pagos: Procesa el pago con la pasarela (ej. Stripe). Si es exitoso, actualiza el estado del pedido a "pagado" y notifica al inventario para reducir stock.
Implementación con gRPC: Cada servicio tiene su servidor gRPC. El servicio de pedidos actúa como orquestador. Ejemplo de flujo en código Go:
// En OrderService (servidor)
func (s *OrderServer) CreateOrder(ctx context.Context, req *pb.CreateOrderRequest) (*pb.OrderResponse, error) {
// 1. Llamar a InventoryService para verificar stock
inventoryClient := pb.NewInventoryServiceClient(inventoryConn)
inventoryResp, err := inventoryClient.CheckStock(ctx, &pb.StockRequest{Items: req.Items})
if err != nil || !inventoryResp.Available {
return &pb.OrderResponse{Status: "failed", Message: "Stock insuficiente"}, nil
}
// 2. Llamar a PaymentService para procesar pago
paymentClient := pb.NewPaymentServiceClient(paymentConn)
paymentResp, err := paymentClient.ProcessPayment(ctx, &pb.PaymentRequest{Amount: req.TotalAmount, UserId: req.UserId})
if err != nil || paymentResp.Status != "success" {
return &pb.OrderResponse{Status: "failed", Message: "Pago fallido"}, nil
}
// 3. Actualizar orden y responder
orderId := generateOrderID()
return &pb.OrderResponse{OrderId: orderId, Status: "completed", Message: "Pedido creado exitosamente"}, nil
}En producción, se deben manejar transacciones distribuidas (Sagas) para mantener consistencia eventual entre servicios.
Errores comunes
- No definir versiones en protobuf: Cambiar campos sin considerar compatibilidad hacia atrás puede romper clientes. Solución: Usar campos opcionales, no eliminar campos numerados, y planificar versiones con cuidado.
- Ignorar timeouts y retries: En microservicios, las llamadas pueden fallar por red o latencia. Solución: Configurar timeouts apropiados (ej. 5-10 segundos) e implementar retries con backoff exponencial.
- Acoplamiento fuerte entre servicios: Si el servicio de pedidos depende directamente de la implementación de inventario, cambios pueden causar errores. Solución: Usar contratos definidos en protobuf y mantener independencia; considerar eventos asíncronos para desacoplar.
- No manejar errores de gRPC: gRPC devuelve códigos de estado específicos (ej. DEADLINE_EXCEEDED, UNAVAILABLE). Solución: Implementar logging y métricas para monitorear, y definir políticas de fallback.
- Olvidar la seguridad: Exponer endpoints gRPC sin autenticación o encriptación. Solución: Usar TLS para encriptar tráfico y tokens (ej. JWT) para autenticación.
Checklist de dominio
- ¿Puedes definir un servicio gRPC con protobuf que incluya al menos dos métodos RPC y mensajes anidados?
- ¿Sabes generar código a partir de archivos .proto para tu lenguaje de programación (ej. Go, Python, Java)?
- ¿Puedes implementar un servidor gRPC que orquestre llamadas a otros dos servicios (ej. inventario y pagos)?
- ¿Entiendes cómo configurar timeouts, retries y balanceo de carga en un cliente gRPC?
- ¿Eres capaz de desplegar los servicios en Kubernetes y configurar service discovery para comunicación?
- ¿Puedes manejar errores comunes como fallos de red o respuestas inesperadas entre servicios?
- ¿Sabes medir el performance de las llamadas gRPC (ej. latencia, throughput) y optimizar según necesidades?
Implementar un flujo completo de pedido con gRPC en Kubernetes
En este ejercicio, crearás un sistema de tres microservicios (pedidos, inventario, pagos) que se comuniquen via gRPC y los desplegarás en un cluster de Kubernetes. Sigue estos pasos:
- Preparar el entorno: Asegúrate de tener Docker, Kubernetes (ej. Minikube o Kind) y el compilador protoc instalados.
- Definir protobuf: Crea tres archivos .proto: order.proto, inventory.proto y payment.proto. Define al menos un método RPC en cada uno (ej. CreateOrder, CheckStock, ProcessPayment) con mensajes apropiados.
- Generar código: Usa protoc para generar código en tu lenguaje preferido (ej. Go). Ejecuta comandos como
protoc --go_out=. --go-grpc_out=. *.proto. - Implementar servidores: Escribe el código para cada servicio. El servicio de pedidos debe llamar a inventario para verificar stock y a pagos para procesar el pago, manejando errores y timeouts.
- Construir imágenes Docker: Crea un Dockerfile para cada servicio y construye las imágenes. Etiquétalas apropiadamente (ej. order-service:latest).
- Desplegar en Kubernetes: Crea archivos YAML para Deployments y Services. Usa ClusterIP para comunicación interna. Asegúrate de que los servicios puedan descubrirse por nombre (ej. inventory-service).
- Probar el flujo: Expón el servicio de pedidos mediante NodePort o Ingress. Usa una herramienta como grpcurl o un cliente escrito por ti para enviar una solicitud CreateOrder y verificar que el flujo funcione end-to-end.
- Monitorear y optimizar: Agrega logging básico y métricas (ej. contadores de llamadas exitosas/fallidas). Ajusta timeouts y recursos según sea necesario.
Pistas
- Usa variables de entorno en Kubernetes para configurar endpoints de servicios (ej. INVENTORY_SERVICE_HOST).
- Implementa retries con backoff exponencial en el cliente gRPC para manejar fallos temporales.
- Considera usar un patrón Saga para manejar transacciones distribuidas si necesitas consistencia fuerte.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.
Sigue con Implementación Avanzada de gRPC y Protocol Buffers para Microservicios
Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.
Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.