Saltar al contenido

Lección 1 de 20 · Lectura y práctica

Definir esquemas de datos con Protocol Buffers v3

Concepto claveProtocol Buffers (protobuf) es un mecanismo de serialización de datos desarrollado por Google que permite definir esquemas de datos tipados de manera independiente al lenguaje de programación. A diferencia de JSON o.

Del concepto a la práctica

Taller de esta lección

Un esquema útil no solo enumera campos: fija significado, unidad y reglas de evolución. Para una reserva de libro, separar cantidad de precio evita que un consumidor interprete un importe total como valor unitario.

Ejemplo resuelto

proto
syntax = "proto3";
package lab;
message LineaPedido {
  string sku = 1;
  uint32 unidades = 2;
  uint32 precio_centavos = 3;
}

precio_centavos representa un precio UNITARIO de1299 como12,99 EUR; la unidad queda explícita y el campo 3 no se reutiliza.

uint32 admite cero por defecto; el esquema no garantiza cantidades positivas. Valida unidades>=1, moneda admitida y límites de precio al recibir la solicitud. Un mensaje tipado puede ser semánticamente inválido. Al retirar un campo reserva su número y su nombre; conserva centavos enteros para este laboratorio. No extrapoles cifras de velocidad del material original: mide tamaños/latencias con tus propios mensajes.

Pruébalo

  1. Añade string moneda = 4 y conserva los números existentes.

  2. Escribe dos registros: BK-7, 2, 1299, EUR y BK-8, 1, 850, EUR.

  3. Calcula el total: 2×1299 + 1×850 = 3448 centavos.

Error frecuente: cambiar unidades por texto para aceptar cualquier entrada. Corrección: valida la entrada antes del mensaje y conserva el tipo numérico.

Comprueba tu resultado

Ejercicio: diseña DireccionEntrega con calle, ciudad y código postal, asignando números únicos. Resultado esperado: ningún número se repite, cada campo tiene una unidad o significado claro y el total anterior es 3448 centavos.

Diagrama de decisión con ramas Sí y No y un bucle que procesa cada elemento de una lista.
CursaloMapa de práctica
Cómo avanza un programa

Una 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

Protocol Buffers (protobuf) es un mecanismo de serialización de datos desarrollado por Google que permite definir esquemas de datos tipados de manera independiente al lenguaje de programación. A diferencia de JSON o XML, protobuf utiliza archivos .proto para describir la estructura de los datos, generando luego código en múltiples lenguajes (Go, Java, Python, etc.) que serializa y deserializa de forma eficiente.

Imagina que estás construyendo un sistema de reservas de hotel donde diferentes microservicios (reservas, pagos, notificaciones) necesitan intercambiar información sobre una reserva. Con JSON, cada servicio podría interpretar los campos de manera ligeramente diferente, causando errores. Con protobuf, defines una vez el esquema de "Reserva" en un archivo .proto, y todos los servicios usan el mismo código generado, asegurando consistencia y tipos de datos correctos. La versión 3 (proto3) simplifica la sintaxis eliminando características como campos requeridos y valores por defecto explícitos, enfocándose en simplicidad y compatibilidad hacia adelante.

Cómo funciona en la práctica

Para definir un esquema con proto3, creas un archivo .proto con sintaxis específica. Veamos un ejemplo paso a paso para un sistema de e-commerce:

syntax = "proto3";

package ecommerce;

message Producto {
    string id = 1;
    string nombre = 2;
    float precio = 3;
    int32 stock = 4;
    repeated string categorias = 5;
    bool activo = 6;
}

message Carrito {
    string usuario_id = 1;
    repeated Producto productos = 2;
    float total = 3;
}

Explicación de los elementos clave:

  • syntax = "proto3": Especifica que usas la versión 3.
  • package ecommerce: Organiza los mensajes en un namespace para evitar conflictos.
  • message: Define un tipo de dato, similar a una clase o struct.
  • Campos: Cada campo tiene un tipo (string, float, int32, bool), un nombre y un número único (etiqueta) usado en la serialización binaria.
  • repeated: Indica una lista o array del tipo especificado.

Una vez definido, usas el compilador protoc para generar código. Por ejemplo, en Go: protoc --go_out=. producto.proto. Esto crea structs Go con métodos para serializar a bytes y deserializar desde bytes, optimizados para velocidad y tamaño.

Caso de estudio

En un sistema de microservicios para una plataforma de streaming de video, necesitas definir esquemas para usuarios, videos y reproducciones. Aquí un ejemplo realista:

syntax = "proto3";

package streaming;

import "google/protobuf/timestamp.proto";

message Usuario {
    string id = 1;
    string email = 2;
    string nombre = 3;
    google.protobuf.Timestamp fecha_registro = 4;
    enum Plan {
        BASICO = 0;
        PREMIUM = 1;
        FAMILIAR = 2;
    }
    Plan plan_actual = 5;
}

message Video {
    string id = 1;
    string titulo = 2;
    int32 duracion_segundos = 3;
    repeated string generos = 4;
    map metadatos = 5; // Ejemplo: {"director": "Juan Pérez", "año": "2023"}
}

message EventoReproduccion {
    string usuario_id = 1;
    string video_id = 2;
    google.protobuf.Timestamp inicio = 3;
    google.protobuf.Timestamp fin = 4;
    bool completado = 5;
}

Este esquema permite:

  • Tipos complejos como Timestamp de la biblioteca estándar de protobuf para fechas.
  • Enums para valores predefinidos (Plan).
  • Mapas para pares clave-valor dinámicos (metadatos).
  • Los microservicios de usuario, catálogo y analytics pueden intercambiar datos sin ambigüedades, reduciendo bugs en producción.
En pruebas de rendimiento, protobuf serializa hasta 6 veces más rápido y ocupa 3 veces menos espacio que JSON en casos típicos, crucial para microservicios de alta escala.

Errores comunes

  1. No usar números de campo únicos o reutilizarlos: Cada campo en un message debe tener un número único (1, 2, 3...). Si reusas un número, el compilador dará error. Solución: Asigna números secuenciales y documenta cambios en versiones futuras.
  2. Olvidar que los campos son opcionales por defecto en proto3: A diferencia de proto2, todos los campos en proto3 son opcionales, lo que puede llevar a validaciones faltantes. Solución: Implementa validaciones en el código generado o usa herramientas como protoc-gen-validate.
  3. No planear la evolución del esquema: Cambiar tipos de campos (ej., de int32 a string) puede romper compatibilidad. Solución: Sigue las reglas de compatibilidad de protobuf: no cambiar números de campo, usar reserved para campos obsoletos, y añadir nuevos campos al final.
  4. Ignorar el paquete (package): Sin package, puede haber conflictos de nombres entre esquemas. Solución: Siempre define un package único, como "com.empresa.microservicio".
  5. Serializar sin compresión en redes lentas: Aunque protobuf es compacto, no comprime por defecto. Solución: Usa gzip o técnicas similares en la capa de transporte para grandes volúmenes de datos.

Checklist de dominio

  • Puedo definir un message proto3 con tipos básicos (string, int32, float, bool) y repetidos (repeated).
  • Sé cómo importar y usar tipos complejos como Timestamp de la biblioteca estándar.
  • He utilizado enums y maps en esquemas realistas para microservicios.
  • Entiendo las reglas de compatibilidad para evolucionar esquemas sin romper clientes existentes.
  • Puedo generar código en al menos un lenguaje (ej., Go o Python) y serializar/deserializar datos.
  • He probado el tamaño y velocidad de serialización comparado con JSON en un caso simple.
  • Sé cómo estructurar paquetes y organizar múltiples archivos .proto en un proyecto.

Definir un esquema proto3 para un sistema de pedidos de restaurante

En este ejercicio, crearás un esquema Protocol Buffers v3 para un microservicio de pedidos en un restaurante. Sigue estos pasos:

  1. Crea un archivo llamado pedidos.proto en un directorio de trabajo.
  2. Define el esquema con las siguientes especificaciones:
    • Usa syntax = "proto3" y un package llamado restaurante.pedidos.
    • Crea un message ItemPedido con campos: id (string), nombre (string), cantidad (int32), precio_unitario (float).
    • Crea un message Pedido con campos: id (string), usuario_id (string), estado (usa un enum con valores: PENDIENTE, EN_PROCESO, COMPLETADO, CANCELADO), items (repeated ItemPedido), total (float), timestamp (google.protobuf.Timestamp).
    • Importa el tipo Timestamp desde google/protobuf/timestamp.proto.
  3. Genera el código en un lenguaje de tu elección (ej., Go o Python). Si usas Go, ejecuta: protoc --go_out=. --go_opt=paths=source_relative pedidos.proto.
  4. Escribe un pequeño programa que:
    • Cree una instancia de Pedido con datos de ejemplo.
    • Serialice a bytes usando el código generado.
    • Deserialice de vuelta y verifique que los datos coincidan.
  5. Opcional: Añade un campo map a Pedido para notas especiales (ej., "sin gluten").
Pistas
  • Recuerda que los números de campo deben ser únicos dentro de cada message, empieza con 1 para el primer campo.
  • Para el enum, define los valores en mayúsculas y asigna 0 al primero (ej., PENDIENTE = 0).
  • Si tienes errores de importación, asegúrate de tener los archivos .proto de Google en tu ruta o usa una opción como -I en protoc.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Práctica acompañada: Una app que cabe en tu día

Un proyecto pequeño con React Native y Expo. Usa este cuaderno como práctica complementaria de la ruta; el material original de la lección continúa siendo tu referencia.

Un proyecto pequeño con React Native y Expo: Pantalla, Acción, Permiso, Dispositivo
De la idea al resultado: una secuencia para practicar y revisar.

Práctica: prueba en cuatro condiciones

Completa el flujo con una imagen vertical, una horizontal, cancelando el selector y negando el permiso. Comprueba que la aplicación conserva proporciones y que ningún control queda fuera de alcance. Repite al volver del fondo y al cambiar el tamaño del texto.

Si tu proyecto permite guardar la imagen, verifica por separado el permiso y el resultado de guardado. No muestres «Guardado» antes de que la operación termine. Usa archivos de prueba propios. Para comparar versiones, conserva capturas con el mismo dispositivo, orientación y tamaño de letra.

Comprueba tu entrega

Entrega el repositorio con instrucciones, la lista de versiones y la matriz de dispositivos. Incluye una captura de cada estado y un video propio breve que muestre el recorrido entero, incluida la cancelación. No hace falta publicar una app para demostrar este aprendizaje.

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.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.