Incontra Bond, Microsoft Bond: un nuovo framework di serializzazione dei dati

Pubblicato: 2022-03-11

Microsoft Bond è un nuovo framework di serializzazione per dati schematizzati creato da Microsoft.

Ricapitoliamo dove viene utilizzata maggiormente la serializzazione dei dati:

  • Persistenza dei dati in file, flussi, NoSQL e BigData.
  • Trasmissione dati in reti, IPC, ecc.

Comunemente, queste applicazioni hanno a che fare con dati schematizzati, dove schema significa:

  • Struttura: gerarchia, relazioni, ordine.
  • Semantica: età in numero di anni dalla nascita.

framework di serializzazione dei dati di Microsoft Bond

In realtà, qualsiasi dato ha uno schema anche se è implicitamente definito o supportato dal tuo linguaggio di programmazione predefinito. Quando si tratta di strutture dati complesse, finiamo per scrivere oggetti di trasferimento dati di supporto (DTO) e codice responsabile dell'IO, spesso in linguaggi diversi. Non appena cresce e si evolve, diventa rapidamente un incubo mantenere tutti questi pezzi. È qui che i framework di serializzazione vincono la partita.

Prima di tutto, qualsiasi framework di serializzazione definisce un'astrazione per la definizione dello schema di dati che non è vincolata a un particolare linguaggio di programmazione o piattaforma. Questa astrazione è nota come DSL (linguaggio specifico del dominio).

Avendo un tale DSL, possiamo definire lo schema dei dati per una particolare applicazione. La definizione, a sua volta, può essere espressa in più forme, ma spesso i framework di serializzazione supportano un unico modulo che ben si adatta alla sua DSL. Troppo complicato? Ecco un esempio ben noto: XSD e XML.

XSD definisce un DSL, XML è (consigliato) per definire documenti che corrispondono allo schema XSD. Ma puoi anche usare "xsd.exe" per generare classi DTO corrispondenti all'XSD, quindi le classi generate sono solo un'altra forma. Nota che puoi generare XML da DTO e viceversa e saranno semanticamente identici, perché la semantica è comune: è definita con l'XSD. Per riassumere, un framework di serializzazione fornisce un DSL, che usi per definire schemi di dati in un determinato formato che è supportato al meglio dal framework dato.

Lo schema di dati astratto sarà infine materializzato in un insieme di entità espresse in un linguaggio di programmazione. Tutti i framework di serializzazione forniscono strumenti speciali chiamati generatori di codice.

Generano tutto il codice di supporto per i linguaggi di programmazione di destinazione, necessario per consentire ai client di lavorare con dati schematizzati: DTO, proxy, ecc. Questo è necessario in definitiva per i linguaggi fortemente tipizzati, mentre può essere opzionale per i linguaggi tipizzati (dinamici) .

L'ultima ma non meno importante questione è la persistenza dei dati sul filo. I dati effettivi verranno eventualmente serializzati in byte grezzi (o testo) e deserializzati nuovamente.

Tutti i framework di serializzazione dei dati forniscono un'altra astrazione qui chiamata protocolli. Un protocollo definisce un insieme di regole che definiscono come i dati strutturati devono essere serializzati o deserializzati in base al relativo schema. Ogni protocollo è normalmente implementato per tutti i linguaggi di programmazione e le piattaforme supportati da un determinato framework di serializzazione. Più linguaggi/piattaforme di programmazione supporta, più implementazioni fornirà.

Immagina che un framework sia disposto a supportare il protocollo JSON, quindi deve fornire un lettore/scrittore JSON per dire C#, C++, Windows, Linux, ecc.

Mettendo tutto insieme: qualsiasi moderno framework di serializzazione dei dati fornisce quanto segue:

  • Astrazioni: DSL e Protocolli.
  • Strumenti di generazione del codice.
  • Implementazioni del protocollo.

Microsoft Bond è un moderno framework di serializzazione dei dati. Fornisce potenti protocolli DSL e flessibili, generatori di codice per C++ e C#, efficienti implementazioni di protocolli per Windows, Linux e Mac OS X.

Per diversi anni Bond è rimasta una tecnologia solo per uso interno, ma grazie all'iniziativa Microsoft Open Source, Bond è stato reso disponibile su GitHub: Microsoft Bond.

Concorrenti per la serializzazione dei dati

La rivalità tra i giganti del software ha portato alla comparsa di numerosi framework di serializzazione:

  • Google Inc. - Buffer protocollo Google
  • Facebook Inc. - Thrift, che ora è gestito da Apache
  • Software Apache Foundation - Avro

Ovviamente, sono tutti incompatibili, il che va bene a meno che tu non crei la tua API pubblica usando uno di questi.

Ognuno di loro ha pro e contro, quindi puoi sceglierli in base alle tue esigenze.

Perché Bond?

La risposta ufficiale a questa domanda è qui: “Why Bond”.

Ecco il breve riassunto:

  • Bond supporta il sistema di tipo avanzato inclusi i generici.
  • Bond supporta il controllo delle versioni dello schema e la compatibilità bidirezionale.
  • Bond supporta la manipolazione dello schema di runtime.
  • Bond supporta diverse collezioni: “vector , carta geografica , elenco ”.
  • Bond supporta la serializzazione lazy type-safe: "bonded "
  • Bond supporta protocolli (formati) collegabili con marshalling e transcodifica

Una nota importante è che Bond segue la strategia "pay to play". Più funzioni aggiungi/utilizza, più paghi per dimensioni e velocità. Questo offre agli sviluppatori una grande flessibilità.

Siamo onesti ed elenchiamo anche gli svantaggi:

  • Bond punta allo stack Microsoft con il supporto di C++ e C#, ma non supporta Java (ancora).
  • Bond non supporta il tipo di unione ("oneof" in protobuf).

E per quanto riguarda le prestazioni?

Quando si tratta di confrontare un framework con un altro, gli sviluppatori sono spesso alla ricerca di confronti delle prestazioni. Ma ricordiamo che questi framework sono costituiti da DSL, generatori di codice e protocolli. Se consideri solo le prestazioni dei protocolli, ti mancheranno le funzionalità fornite da DSL e codegen. A volte, avere una DSL migliore è molto più importante che avere una piccola differenza percentuale nella velocità di serializzazione.

Oltre alla velocità, potrebbero essere importanti anche le codifiche efficienti in termini di spazio supportate da alcuni protocolli. Ti incoraggio a fare un confronto tra prestazioni/spazio con i dati specifici del tuo dominio. Questo è l'unico modo per stimare tutti i vantaggi che potresti ottenere da un particolare framework.

legame Microsoft

Questo articolo viene fornito con il progetto demo che dimostra l'utilizzo del framework Bond leggendo tutti i record dal registro eventi dell'applicazione Windows, serializzandoli come oggetti Bond e deserializzandoli nuovamente.

Per compilare ed eseguire la demo, non è necessario installare alcun software diverso da Visual Studio.

Utilizzo di Microsoft Bond

Ottenere il legame

Consulta la guida ufficiale su come ottenere Bond per le tue piattaforme.

Per i progetti .NET, questo è semplice come:

 install-package Bond.CSharp

Il pacchetto include:

  • Generatore di codice (gbc.exe) nella cartella bin
  • Librerie .NET
  • Attività di MSBuild

Flusso di lavoro

Il flusso di lavoro include i seguenti passaggi:

  • Impara DSL e definisci lo schema dei dati scrivendo i file ".bond".
  • Usa il generatore di codice ("gbc.exe") per ottenere DTO per il tuo linguaggio di programmazione.
  • Fare riferimento ai file generati e alle librerie di runtime di Bond nel progetto.

Prendi in considerazione l'utilizzo delle attività MSBuild fornite con il framework per automatizzare il passaggio di generazione del codice.

Panoramica delle funzionalità DSL

Quando inizi a scrivere il tuo primo file ".bond", dovrai conoscerne la sintassi e le caratteristiche. Si prega di visitare la pagina della documentazione ufficiale che descrive l'IDL in dettaglio. Esaminiamo solo le caratteristiche di base:

  • Moduli: lo schema può essere suddiviso in diversi file, inclusi nell'istruzione "import".
  • Spazio dei nomi: ha lo stesso significato di C++/C#.
  • Strutture definite dall'utente: un'unità di definizione del tipo di utente.
  • La dichiarazione in avanti è utile per le strutture di dati ricorsive.
  • Tipi di base: “bool, uint8(fino a 64), int8(fino a 64), float, double, string, wstring”.
  • Tipi di contenitori: “blob, list , vettore , impostare , mappa<K, T>, nullable ”.
  • Alias ​​digitati e mappatura personalizzati, ad esempio se vuoi avere "DateTime" in C#, ma spunta ("int64") sul cavo.
  • Attributi personalizzati: utili per la generazione di codice personalizzato.

Annoiato? Ecco un esempio:

 namespace MyProject struct MyRecord { 0: string Name = "Noname"; 1: vector<double> Constants; }

dove "0" e "1" sono i numeri ordinali del campo (può essere qualsiasi numero intero con qualsiasi passo) e = "Noname" è il valore predefinito (opzionale).

Generazione di codice

Il framework Bond fornisce uno strumento di generazione del codice scritto in Haskell. Ecco come generare codice C# e C++ da uno schema ".bond" nella riga di comando:

 gbc c# example.bond gbc c++ example.bond

Protocolli supportati (formati)

Out of the box Bond supporta tre tipi di protocolli:

  • Protocolli taggati: “CompactBinary” e “FastBinary”

I protocolli contrassegnati interlacciano i metadati dello schema all'interno del payload. Ciò rende il carico utile autodescrittivo, consentendo ai consumatori di interpretarlo anche senza conoscere lo schema utilizzato dal produttore.

  • Protocolli senza tag: “SimpleBinary”

I protocolli senza tag serializzano solo i dati e quindi richiedono che i consumatori conoscano lo schema del carico utile tramite un meccanismo fuori banda. I protocolli senza tag vengono spesso utilizzati negli scenari di archiviazione perché consentono di archiviare uno schema una sola volta (ad esempio in una tabella di sistema in un database), eliminando così l'overhead di metadati da molti record che utilizzano lo stesso schema.

  • Protocolli basati su DOM: "SimpleJson" e "SimpleXml"

Il protocollo basato su DOM analizza l'intero carico utile in un Data Object Model in memoria che viene quindi interrogato durante la deserializzazione. In genere, questo tipo di protocollo viene utilizzato per implementare codifiche basate su testo come JSON o XML.

Per ogni protocollo, la libreria di runtime Bond fornisce le classi Reader e Writer corrispondenti, che svolgono il lavoro sulla serializzazione effettiva.

L'uso dei protocolli è piuttosto semplice e leggermente più difficile del 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);

Qual è il prossimo?

Se ami Bond e hai un sacco di tempo libero per la programmazione, prendi in considerazione l'idea di sviluppare uno di questi elementi. Non elencherò tutti i vantaggi che potresti ottenere dal contributo, ma so che molti sviluppatori sono alla ricerca di idee a cui contribuire:

  • Implementa una porta su Java. Sostituisci Java con altri linguaggi tradizionali a tua scelta.
  • Implementare l'importazione/esportazione dello schema Bond per lo scambio con altri DSL (es. “.proto <=> .bond”).

Qualunque cosa tu decida di fare riguardo a Bond, ti consiglio di contattare prima Adam Sapek. È il capofila di questo progetto e ti guiderà con ciò che è più richiesto dal mercato.