Conozca a Bond, Microsoft Bond: un nuevo marco de serialización de datos
Publicado: 2022-03-11Microsoft Bond es un nuevo marco de serialización para datos esquematizados creado por Microsoft.
Recapitulemos dónde se usa más la serialización de datos:
- Persistencia de datos en archivos, flujos, NoSQL y BigData.
- Transmisión de datos en redes, IPC, etc.
Comúnmente, estas aplicaciones tienen que tratar con datos esquematizados, donde esquema significa:
- Estructura: jerarquía, relaciones, orden.
- Semántica: edad en número de años desde que nació.
En realidad, cualquier dato tiene un esquema, incluso si su lenguaje de programación lo define implícitamente o lo admite de fábrica. Cuando se trata de estructuras de datos complejas, terminamos escribiendo objetos de transferencia de datos (DTO) compatibles y el código responsable de IO, a menudo en diferentes idiomas. Tan pronto como crece y evoluciona, mantener todas estas piezas rápidamente se convierte en una pesadilla. Aquí es donde los marcos de serialización ganan el juego.
En primer lugar, cualquier marco de serialización define una abstracción para la definición del esquema de datos que no está vinculada a un lenguaje de programación o plataforma en particular. Esta abstracción se conoce como DSL (lenguaje específico del dominio).
Con tal DSL, podemos definir el esquema de datos para una aplicación en particular. La definición, a su vez, se puede expresar de múltiples formas, pero a menudo los marcos de serialización admiten una sola forma que se adapta bien a su DSL. ¿Demasiado complicado? Aquí hay un ejemplo bien conocido: XSD y XML.
XSD define un DSL, XML es (recomendado) para definir documentos que coincidan con el esquema XSD. Pero también puede usar "xsd.exe" para generar clases DTO que coincidan con el XSD, por lo tanto, las clases generadas son solo otra forma. Tenga en cuenta que puede generar XML a partir de DTO y viceversa y serán semánticamente idénticos, porque la semántica es común: se define con el XSD. Para resumir, un marco de serialización le proporciona un DSL, que utiliza para definir esquemas de datos en un formato determinado que es mejor compatible con el marco dado.
El esquema de datos abstractos se materializará eventualmente en un conjunto de entidades expresadas en un lenguaje de programación. Todos los marcos de serialización proporcionan herramientas especiales llamadas generadores de código.
Generan todo el código de soporte para los lenguajes de programación de destino, que es necesario para que los clientes trabajen con datos esquematizados: DTO, proxy, etc. En última instancia, esto es necesario para los lenguajes fuertemente tipados, mientras que puede ser opcional para los lenguajes de tipo pato (dinámicos). .
El último, pero no menos importante, es la persistencia de los datos en el cable. Los datos reales se serializarán eventualmente en bytes sin procesar (o texto) y se deserializarán nuevamente.
Todos los marcos de serialización de datos proporcionan aquí otra abstracción llamada protocolos. Un protocolo define un conjunto de reglas que definen cómo se deben serializar o deserializar los datos estructurados de acuerdo con su esquema. Cada protocolo normalmente se implementa para todos los lenguajes de programación y plataformas compatibles con el marco de serialización dado. Cuantos más lenguajes de programación/plataformas admita, más implementaciones proporcionará.
Imagine que un marco está dispuesto a admitir el protocolo JSON, luego debe proporcionar un lector/escritor de JSON para, por ejemplo, C#, C++, Windows, Linux, etc.
Poniéndolo todo junto: cualquier marco de serialización de datos moderno le proporciona lo siguiente:
- Abstracciones: DSL y Protocolos.
- Herramientas de generación de código.
- Implementaciones de protocolo.
Microsoft Bond es un marco de serialización de datos moderno. Proporciona DSL potente y protocolos flexibles, generadores de código para C++ y C#, implementaciones de protocolo eficientes para Windows, Linux y Mac OS X.
Durante varios años, Bond siguió siendo una tecnología solo para uso interno, pero gracias a la iniciativa de código abierto de Microsoft, Bond está disponible en GitHub: Microsoft Bond.
Competidores de serialización de datos
La rivalidad entre los gigantes del software hizo que aparecieran varios marcos de serialización:
- Google Inc. - Búferes de protocolo de Google
- Facebook Inc. - Thrift, que ahora es mantenido por Apache
- Software de la Fundación Apache - Avro
Obviamente, todos son incompatibles, lo cual está bien a menos que haga su API pública usando uno de estos.
Cada uno de ellos tiene ventajas y desventajas, por lo que puede elegirlos según sus necesidades.
¿Por qué Bond?
La respuesta oficial a esta pregunta está aquí: "¿Por qué Bond".
Aquí está el resumen rápido:
- Bond es compatible con el sistema de tipos enriquecidos, incluidos los genéricos.
- Bond admite versiones de esquemas y compatibilidad bidireccional.
- Bond admite la manipulación de esquemas en tiempo de ejecución.
- Bond admite varias colecciones: “vector
, mapa , lista ”. - Bond admite la serialización diferida con seguridad de tipos: "bonded
” - Bond admite protocolos conectables (formatos) con cálculo de referencias y transcodificación
Una nota importante es que Bond sigue la estrategia de "pagar para jugar". Cuantas más funciones agregue o use, más pagará por el tamaño y la velocidad. Esto le da a los desarrolladores una gran flexibilidad.
Seamos honestos y enumeremos también los inconvenientes:
- Bond apunta a la pila de Microsoft con compatibilidad con C ++ y C #, pero sin compatibilidad con Java (todavía).
- Bond no admite el tipo de unión ("oneof" en protobuf).
¿Qué pasa con el rendimiento?
Cuando se trata de comparar un marco con otro, los desarrolladores a menudo buscan comparaciones de rendimiento. Pero recordemos que estos marcos consisten en DSL, generadores de código y protocolos. Si solo tiene en cuenta el rendimiento de los protocolos, se perderá las funciones proporcionadas por DSL y codegens. A veces, tener un mejor DSL es mucho más importante que tener una pequeña diferencia porcentual en la velocidad de serialización.

Además de la velocidad, las codificaciones de uso eficiente del espacio admitidas por algunos protocolos también podrían ser importantes. Le animo a que haga una comparación de rendimiento/espacio con los datos específicos de su dominio. Esta es la única forma de estimar todos los beneficios que podría obtener de un marco en particular.
Este artículo viene con el proyecto de demostración que demuestra el uso del marco Bond al leer todos los registros del Registro de eventos de la aplicación de Windows, serializarlos como objetos Bond y volver a deserializarlos.
Para compilar y ejecutar la demostración, no necesita instalar ningún software que no sea Visual Studio.
Uso de bonos de Microsoft
Obtención de bonos
Consulte la guía oficial sobre cómo obtener Bond para su(s) plataforma(s).
Para proyectos .NET, esto es tan simple como:
install-package Bond.CSharp
El paquete incluye:
- Generador de código (gbc.exe) en la carpeta bin
- Bibliotecas .NET
- Tareas de MSBuild
flujo de trabajo
El flujo de trabajo incluye los siguientes pasos:
- Aprenda DSL y defina el esquema de datos escribiendo archivos ".bond".
- Use el generador de código ("gbc.exe") para obtener DTO para su lenguaje de programación.
- Haga referencia a los archivos generados, así como a las bibliotecas de tiempo de ejecución de Bond en su proyecto.
Considere usar las tareas de MSBuild proporcionadas con el marco para automatizar el paso de generación de código.
Descripción general de las características de DSL
Cuando comience a escribir su primer archivo “.bond”, necesitará conocer su sintaxis y características. Visite la página de documentación oficial que describe el IDL en detalles. Repasemos solo las características básicas:
- Módulos: el esquema se puede dividir en diferentes archivos, que se incluyen con la declaración de "importación".
- Espacio de nombres: tiene el mismo significado que tiene C++/C#.
- Estructuras definidas por el usuario: una unidad de definición de tipo de usuario.
- La declaración directa es útil para estructuras de datos recursivas.
- Tipos básicos: "bool, uint8 (hasta 64), int8 (hasta 64), float, double, string, wstring".
- Tipos de contenedor: "blob, lista
, vectorial , colocar , mapa<K, T>, anulable ”. - Mapeo y alias escritos personalizados, por ejemplo, si desea tener "DateTime" en C#, pero marca ("int64") en el cable.
- Atributos personalizados: útil para la generación de código personalizado.
¿Aburrido? Aquí hay un ejemplo:
namespace MyProject struct MyRecord { 0: string Name = "Noname"; 1: vector<double> Constants; }
donde "0" y "1" son los números ordinales de campo (pueden ser números enteros con cualquier ritmo) y = "Noname"
es el valor predeterminado (opcional).
Codigo de GENERACION
Bond Framework proporciona una herramienta de generación de código escrita en Haskell. Aquí se explica cómo generar código C# y C++ a partir de un esquema “.bond” en la línea de comandos:
gbc c# example.bond gbc c++ example.bond
Protocolos admitidos (formatos)
Bond, listo para usar, admite tres tipos de protocolos:
- Protocolos etiquetados: “CompactBinary” y “FastBinary”
Los protocolos etiquetados intercalan metadatos de esquema dentro de la carga útil. Esto hace que la carga útil se describa a sí misma, lo que permite a los consumidores interpretarla incluso sin conocer el esquema utilizado por el productor.
- Protocolos sin etiquetar: “SimpleBinary”
Los protocolos sin etiqueta serializan solo datos y, por lo tanto, requieren que los consumidores conozcan el esquema de carga útil a través de algún mecanismo fuera de banda. Los protocolos sin etiquetar a menudo se usan en escenarios de almacenamiento porque permiten almacenar un esquema una vez (por ejemplo, en una tabla del sistema en una base de datos), eliminando así la sobrecarga de metadatos de muchos registros que usan el mismo esquema.
- Protocolos basados en DOM: “SimpleJson” y “SimpleXml”
El protocolo basado en DOM analiza toda la carga útil en un modelo de objeto de datos en memoria que luego se consulta durante la deserialización. Normalmente, este tipo de protocolo se utiliza para implementar codificaciones basadas en texto, como JSON o XML.
Para cada protocolo, la biblioteca de tiempo de ejecución de Bond le proporciona las clases Reader y Writer correspondientes, que hacen el trabajo en la serialización real.
Usar los protocolos es bastante sencillo y un poco más difícil que el famoso "JsonConvert.SerializeObject()":
var record = new MyRecord { Name = "FooBar", Constants = { 3.14, 6.28 } }; var output = new OutputBuffer(); var writer = new CompactBinaryWriter<OutputBuffer>(output); Serialize.To(writer, record); var input = new InputBuffer(output.Data); var reader = new CompactBinaryReader<InputBuffer>(input); record = Deserialize<Example>.From(reader);
¿Que sigue?
Si te encanta Bond y tienes mucho tiempo libre para programar, considera desarrollar uno de estos elementos. No enumeraré todos los beneficios que puede obtener al contribuir, pero sé que muchos desarrolladores están buscando ideas para contribuir:
- Implementar un puerto a Java. Reemplace Java con otros lenguajes principales a su elección.
- Implemente la importación/exportación de esquemas de bonos para intercambiar con otros DSL (p. ej., “.proto <=> .bond”).
Independientemente de lo que decidas hacer con respecto a Bond, te recomiendo que primero te comuniques con Adam Sapek. Él es el líder de este proyecto y te guiará con lo que más demanda el mercado.