Elegir el formato correcto para intercambiar datos entre servicios puede marcar una diferencia enorme en el rendimiento de tu aplicación. JSON y Protocol Buffers son dos opciones con fortalezas distintas, y entender sus diferencias te permitirá tomar decisiones técnicas más acertadas según el contexto de tu proyecto.
¿Cómo funciona la serialización en JSON?
JSON nació gracias a JavaScript y define una estructura de datos basada en llaves y valores [0:25]. Por ejemplo, una llave como foo con un valor bar. A simple vista, cualquier persona puede leer un archivo JSON y entender qué forma tiene la data. Esto lo convierte en un formato muy legible a nivel humano.
Sin embargo, cuando un lenguaje de programación como Go, Python o C++ necesita leer esa data, las cosas se complican [0:50]. El proceso de serialización consiste en convertir una estructura de datos nativa del lenguaje, como un struct en Go, a formato JSON para enviarlo al cliente. Este proceso es considerado relativamente lento, ya que puede tomar bastantes nanosegundos.
Del otro lado ocurre lo mismo: cuando un servidor recibe un JSON, debe deserializarlo, es decir, transformar ese JSON de vuelta a una estructura de datos utilizable en el lenguaje correspondiente [1:18]. Ambos procesos, serialización y deserialización, impactan directamente el rendimiento de la aplicación.
¿Por qué JSON sigue siendo el estándar de la web?
- Es muy fácil de leer para cualquier persona.
- Ofrece gran flexibilidad, ya que puedes crear estructuras de datos al vuelo.
- Es el estándar en REST APIs y la forma predominante de comunicación web [3:20].
¿Qué ventajas ofrecen los Protocol Buffers en rendimiento?
Los Protocol Buffers funcionan de manera diferente. Primero defines un archivo .proto, luego un compilador genera el paquete correspondiente para Go, Python, PHP o el lenguaje que necesites [1:55]. Este proceso intermedio de compilación solo ocurre una vez, o cuando modificas el archivo proto, no mientras tu aplicación está corriendo.
Una ventaja fundamental es que los protobuffers son agnósticos del lenguaje de programación [2:20]. Están definidos dentro de su propia sintaxis, lo que significa que puedes compartir el mismo archivo .proto con equipos que trabajen en lenguajes distintos sin problemas de compatibilidad. El proto garantiza que las estructuras de datos funcionarán de la misma manera independientemente del lenguaje.
¿Por qué la serialización es más rápida con protobuffers?
Gracias a que los protobuffers indican en qué posición están los campos [2:48], el proceso de serialización y deserialización es significativamente más rápido que con JSON. Cuando un servidor de Go serializa un struct al formato definido por el proto, la operación ocurre con menor latencia [3:08]. Lo mismo aplica para la deserialización: el tiempo que tarda en cambiar formatos de dato es menor.
¿Cuándo elegir JSON y cuándo Protocol Buffers?
La decisión depende del caso de uso específico de tu aplicación:
Elige JSON cuando:
- La flexibilidad de la data es prioritaria.
- El performance no es un factor crítico.
- Necesitas compatibilidad directa con el ecosistema web y REST APIs.
Elige Protocol Buffers cuando:
- Tu aplicación necesita correr muy rápido [4:02].
- Los procesos de serialización y deserialización deben ser lo más eficientes posible.
- Quieres reutilizar código importando archivos proto dentro de otros archivos proto [3:48].
- Necesitas compartir librerías entre diferentes repositorios y equipos con distintos lenguajes.
Los protobuffers son más difíciles de leer a nivel humano y menos flexibles, ya que requieren definir todas las estructuras de dato previamente. Pero esa rigidez es también su fortaleza: te da consistencia y velocidad.
Ambos formatos tienen su lugar. Lo importante es evaluar si tu prioridad es la legibilidad y flexibilidad, o si el rendimiento y la compatibilidad entre servicios son lo que tu arquitectura necesita. ¿Cuál has utilizado en tus proyectos y qué resultado te ha dado?