Découvrez Bond, Microsoft Bond - Un nouveau cadre de sérialisation des données
Publié: 2022-03-11Microsoft Bond est un nouveau cadre de sérialisation pour les données schématisées créé par Microsoft.
Récapitulons où la sérialisation des données est la plus utilisée :
- Persistance des données dans les fichiers, les flux, NoSQL et BigData.
- Transmission de données dans les réseaux, IPC, etc.
Généralement, ces applications doivent traiter des données schématisées, où schéma signifie :
- Structure : hiérarchie, relations, ordre.
- Sémantique : âge en nombre d'années depuis la naissance.
En fait, toutes les données ont un schéma même si elles sont implicitement définies ou prises en charge par votre langage de programmation prêt à l'emploi. Lorsqu'il s'agit de structures de données complexes, nous finissons par écrire des objets de transfert de données (DTO) et du code responsable des E/S, souvent dans des langages différents. Dès qu'il grandit et évolue, cela devient vite un cauchemar d'entretenir toutes ces pièces. C'est ici que les frameworks de sérialisation gagnent la partie.
Tout d'abord, tout cadre de sérialisation définit une abstraction pour la définition du schéma de données qui n'est pas liée à un langage de programmation ou à une plate-forme particulière. Cette abstraction est connue sous le nom de DSL (langage spécifique au domaine).
Avec un tel DSL, nous pouvons définir un schéma de données pour une application particulière. La définition, à son tour, peut être exprimée sous plusieurs formes, mais souvent les cadres de sérialisation prennent en charge une seule forme bien adaptée à son DSL. Trop compliqué? Voici un exemple bien connu : XSD et XML.
XSD définit un DSL, XML est (recommandé) pour définir les documents correspondant au schéma XSD. Mais, vous pouvez également utiliser "xsd.exe" pour générer des classes DTO correspondant au XSD, par conséquent, les classes générées ne sont qu'une autre forme. Notez que vous pouvez générer du XML à partir de DTO et inversement et qu'ils seront sémantiquement identiques, car la sémantique est commune : elle est définie avec le XSD. Pour résumer, un framework de sérialisation vous fournit un DSL, que vous utilisez pour définir des schémas de données dans un certain format qui est mieux pris en charge par le framework donné.
Le schéma de données abstrait doit être éventuellement matérialisé en un ensemble d'entités exprimées dans un langage de programmation. Tous les frameworks de sérialisation fournissent des outils spéciaux appelés générateurs de code.
Ils génèrent tout le code de support pour les langages de programmation cibles, ce qui est nécessaire pour que les clients travaillent avec des données schématisées : DTO, proxy, etc. Ceci est finalement requis pour les langages fortement typés, alors que cela peut être facultatif pour les langages de type canard (dynamiques). .
Le dernier point, mais non le moindre, est la persistance des données sur le réseau. Les données réelles doivent éventuellement être sérialisées en octets bruts (ou texte) et désérialisées en retour.
Tous les cadres de sérialisation de données fournissent ici une autre abstraction appelée protocoles. Un protocole définit un ensemble de règles qui définissent comment les données structurées doivent être sérialisées ou désérialisées selon leur schéma. Chaque protocole est normalement implémenté pour tous les langages de programmation et plates-formes pris en charge par un cadre de sérialisation donné. Plus il prend en charge de langages de programmation/plates-formes, plus il fournira d'implémentations.
Imaginez qu'un framework soit prêt à prendre en charge le protocole JSON, il doit alors fournir un lecteur/graveur JSON pour, par exemple, C#, C++, Windows, Linux, etc.
En résumé : tout cadre de sérialisation de données moderne vous offre les éléments suivants :
- Abstractions : DSL et protocoles.
- Outils de génération de code.
- Implémentations de protocole.
Microsoft Bond est un framework de sérialisation de données moderne. Il fournit des protocoles DSL puissants et flexibles, des générateurs de code pour C++ et C#, des implémentations de protocoles efficaces pour Windows, Linux et Mac OS X.
Pendant plusieurs années, Bond est resté une technologie à usage interne uniquement, mais grâce à l'initiative Microsoft Open Source, Bond a été rendu disponible sur GitHub : Microsoft Bond.
Concurrents de la sérialisation des données
La rivalité entre les géants du logiciel a conduit à l'apparition d'un certain nombre de frameworks de sérialisation :
- Google Inc. - Tampons de protocole Google
- Facebook Inc. - Thrift, qui est maintenant maintenu par Apache
- Logiciel Apache Foundation - Avro
Évidemment, ils sont tous incompatibles, ce qui est acceptable à moins que vous ne rendiez votre API publique en utilisant l'un d'entre eux.
Chacun d'eux a des avantages et des inconvénients, vous pouvez donc choisir parmi eux en fonction de vos besoins.
Pourquoi Bond ?
La réponse officielle à cette question est ici : "Pourquoi Bond".
Voici le résumé rapide :
- Bond prend en charge le système de type riche, y compris les génériques.
- Bond prend en charge la gestion des versions de schéma et la compatibilité bidirectionnelle.
- Bond prend en charge la manipulation de schéma d'exécution.
- Bond prend en charge diverses collections : « vector
, carte , liste ”. - Bond prend en charge la sérialisation paresseuse sécurisée : "bonded
” - Bond prend en charge les protocoles enfichables (formats) avec marshaling et transcodage
Une note importante est que Bond suit la stratégie « payer pour jouer ». Plus vous ajoutez/utilisez de fonctionnalités, plus vous payez pour la taille et la vitesse. Cela donne aux développeurs une grande flexibilité.
Soyons honnêtes et énumérons également les inconvénients :
- Bond cible la pile Microsoft avec la prise en charge de C++ et C#, mais ne prend pas (encore) en charge Java.
- Bond ne prend pas en charge le type d'union ("oneof" dans protobuf).
Qu'en est-il des performances ?
Lorsqu'il s'agit de comparer un framework à un autre, les développeurs recherchent souvent des comparaisons de performances. Mais rappelons que ces frameworks sont constitués de DSL, de générateurs de code et de protocoles. Si vous ne considérez que les performances des protocoles, vous manquerez les fonctionnalités fournies par DSL et les codegens. Parfois, avoir un meilleur DSL est bien plus important que d'avoir une différence de quelques pour cent dans la vitesse de sérialisation.

Outre la vitesse, les encodages économes en espace pris en charge par certains protocoles pourraient également être importants. Je vous encourage à faire une comparaison performance/espace avec les données spécifiques à votre domaine. C'est la seule façon d'estimer tous les avantages que vous pourriez tirer d'un cadre particulier.
Cet article est fourni avec le projet de démonstration qui illustre l'utilisation du framework Bond en lisant tous les enregistrements du journal des événements d'application Windows, en les sérialisant en tant qu'objets Bond et en les désérialisant.
Pour créer et exécuter la démo, vous n'avez pas besoin d'installer de logiciel autre que Visual Studio.
Utilisation de Microsoft Bond
Obtenir un lien
Consultez le guide officiel pour obtenir Bond pour votre ou vos plateformes.
Pour les projets .NET, c'est aussi simple que :
install-package Bond.CSharp
Le forfait comprend :
- Générateur de code (gbc.exe) dans le dossier bin
- Bibliothèques .NET
- Tâches MSBuild
Flux de travail
Le flux de travail comprend les étapes suivantes :
- Apprenez le DSL et définissez le schéma de données en écrivant des fichiers ".bond".
- Utilisez le générateur de code ("gbc.exe") pour obtenir des DTO pour votre langage de programmation.
- Référencez les fichiers générés ainsi que les bibliothèques d'exécution Bond dans votre projet.
Envisagez d'utiliser les tâches MSBuild fournies avec le framework pour automatiser l'étape de génération de code.
Présentation des fonctionnalités DSL
Lorsque vous commencerez à écrire votre premier fichier « .bond », vous aurez besoin de connaître sa syntaxe et ses fonctionnalités. Veuillez visiter la page de documentation officielle décrivant l'IDL en détail. Passons en revue les fonctionnalités de base :
- Modules : le schéma peut être divisé en différents fichiers, qui sont inclus avec l'instruction "import".
- Espace de noms : a la même signification que C++/C#.
- Structures définies par l'utilisateur : une unité de définition de type d'utilisateur.
- La déclaration directe est utile pour les structures de données récursives.
- Types de base : "bool, uint8(jusqu'à 64), int8(jusqu'à 64), float, double, string, wstring".
- Types de conteneur : "blob, liste
, vecteur , ensemble , carte<K, T>, nullable ”. - Alias typés personnalisés et mappage, par exemple si vous voulez avoir "DateTime" en C #, mais ticks ("int64") sur le fil.
- Attributs personnalisés : utiles pour la génération de code personnalisé.
Ennuyait? Voici un exemple:
namespace MyProject struct MyRecord { 0: string Name = "Noname"; 1: vector<double> Constants; }
où « 0 » et « 1 » sont les nombres ordinaux de champ (peuvent être n'importe quels nombres entiers avec n'importe quel rythme) et = "Noname"
est la valeur par défaut (facultative).
Génération de codes
Le framework Bond fournit un outil de génération de code écrit en Haskell. Voici comment générer du code C# et C++ à partir d'un schéma ".bond" en ligne de commande :
gbc c# example.bond gbc c++ example.bond
Protocoles pris en charge (formats)
Prêt à l'emploi, Bond prend en charge trois types de protocoles :
- Protocoles tagués : "CompactBinary" et "FastBinary"
Les protocoles balisés entrelacent les métadonnées du schéma dans la charge utile. Cela rend la charge utile auto-descriptive, permettant aux consommateurs de l'interpréter même sans connaître le schéma utilisé par le producteur.
- Protocoles non tagués : "SimpleBinary"
Les protocoles non étiquetés ne sérialisent que les données et exigent donc que les consommateurs connaissent le schéma de charge utile via un mécanisme hors bande. Les protocoles non balisés sont souvent utilisés dans les scénarios de stockage car ils permettent de stocker un schéma une seule fois (par exemple dans une table système d'une base de données), éliminant ainsi la surcharge de métadonnées de nombreux enregistrements utilisant le même schéma.
- Protocoles basés sur DOM : "SimpleJson" et "SimpleXml"
Le protocole basé sur DOM analyse toute la charge utile dans un modèle d'objet de données en mémoire qui est ensuite interrogé lors de la désérialisation. Généralement, ce type de protocole est utilisé pour implémenter des encodages textuels tels que JSON ou XML.
Pour chaque protocole, la bibliothèque d'exécution Bond vous fournit les classes Reader et Writer correspondantes, qui effectuent le travail sur la sérialisation réelle.
L'utilisation des protocoles est assez simple, et légèrement plus difficile que ce fameux "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);
Et après?
Si vous aimez Bond et que vous avez beaucoup de temps libre pour coder, envisagez de développer l'un de ces éléments. Je n'énumérerai pas tous les avantages que vous pouvez tirer de votre contribution, mais je sais que de nombreux développeurs recherchent des idées auxquelles contribuer :
- Implémentez un port vers Java. Remplacez Java par d'autres langages courants de votre choix.
- Implémenter l'importation/exportation de schéma Bond pour échanger avec d'autres DSL (par exemple ".proto <=> .bond").
Quoi que vous décidiez de faire concernant Bond, je vous recommande de contacter d'abord Adam Sapek. Il est le chef de file de ce projet et il vous guidera avec ce qui est le plus demandé par le marché.