Julián Duque
Developer and Educator
Image source: Designing Data Intensive Applications, by Martin Kleppmann
1984
1987
1993
1996
1998
2000
2000
2000
2001
2023
Image source: Designing Data Intensive Applications, by Martin Kleppmann
âś” Text based
âś” Schema-less (optional support with json-schema)
âś” Highly supported (Web native)
âś” Widely used in REST APIs, GraphQL, and json-rpc
{
"name": "Baal",
"player": "Julian Duque",
"profession": "Developer and Educator",
"species": "Human",
"playing": true,
"level": 14,
"attributes": {
"strength": 12,
"dexterity": 9,
"constitution": 10,
"intelligence": 13,
"wisdom": 9,
"charisma": 14
},
"proficiencies": [
"node",
"backend",
"rpgs",
"education"
]
}
âś” Schema-less
âś” Smaller than JSON
âś” Not human-readable
âś” Supported by over 50 programming languages and environments
Image source: msgpack.org
$ npm install @msgpack/msgpack
ℹ️ Node.js JSON encoding/decoding is faster
const fs = require('fs')
const path = require('path')
const assert = require('assert')
const { encode, decode } = require('@msgpack/msgpack')
const character = require('./character.json')
const jsonString = JSON.stringify(character)
const characterEncoded = encode(character)
console.log('JSON Size: ', Buffer.byteLength(jsonString))
console.log('MsgPack Size: ', Buffer.byteLength(characterEncoded))
assert.deepStrictEqual(character, decode(characterEncoded))
fs.writeFileSync(path.join(__dirname, 'out', 'character-msgpack.dat'), characterEncoded)
âś” Created by Google
âś” Schema-based
âś” Super fast and small
âś” Support for code generation
âś” Can define a protocol for RPC
syntax = "proto3";
message Character {
message Attribute {
int32 strength = 1;
int32 dexterity = 2;
int32 constitution = 3;
int32 intelligence = 4;
int32 wisdom = 5;
int32 charisma = 6;
}
string name = 1;
string player = 2;
string profession = 3;
string species = 4;
int32 level = 5;
bool playing = 6;
Attribute attributes = 7;
repeated string proficiencies = 8;
}
$ npm install protobufjs
const fs = require('fs')
const path = require('path')
const assert = require('assert')
const protobufjs = require('protobufjs')
const character = require('./character.json')
const main = async () => {
const root = await protobufjs.load(path.join(__dirname, 'schema', 'Character.proto'))
const Character = root.lookupType('Character')
const err = Character.verify(character)
if (err) throw err
const message = Character.create(character)
const buffer = Character.encode(message).finish()
console.log('JSON Size: ', Buffer.byteLength(JSON.stringify(character)))
console.log('Protobuf Size: ', Buffer.byteLength(buffer))
const decodeMsg = Character.decode(buffer)
const obj = Character.toObject(decodeMsg)
assert.deepStrictEqual(character, obj)
fs.writeFileSync(path.join(__dirname, 'out', 'character-protobuf.dat'), buffer)
}
main().catch((err) => console.error(err))
protocol Tabletop {
record Attribute {
int strength;
int dexterity;
int constitution;
int intelligence;
int wisdom;
int charisma;
}
record Character {
string name;
string player;
string profession;
string species;
boolean playing = true;
int level;
Attribute attributes;
array<string> proficiencies;
}
}
$ npm install avsc
âś” Project by the Apache Foundation
âś” Started as part of Hadoop
âś” Schema-based (JSON / IDL)
✔ Super fast and small 🚀
âś” Can define a protocol for RPC
const fs = require('fs')
const path = require('path')
const assert = require('assert')
const avro = require('avsc')
const character = require('./character.json')
const schema = fs.readFileSync(path.join(__dirname, 'schema', 'Character.avsc'), 'utf8')
const type = avro.Type.forSchema(JSON.parse(schema))
const buffer = type.toBuffer(character)
const value = type.fromBuffer(buffer)
console.log('JSON Size: ', Buffer.byteLength(JSON.stringify(character)))
console.log('Avro Size: ', Buffer.byteLength(buffer))
assert(type.isValid(character))
assert.deepEqual(value, character)
fs.writeFileSync(path.join(__dirname, 'out', 'character-avro.dat'), buffer)
âś” MsgPack is supported by Redis Lua and TreasureData
âś” Avro is used in many databases and data-heavy services:
BigQuery
Hadoop
Cloudera Impala
AWS Athena
âś” MsgPack is supported by ZeroRPC
âś” Protocol Buffers is the main standard for gRPC
âś” Avro has its own RPC implementation
âś” Both Protocol Buffers and Avro are widely supported in Apache Kafka
âś” Kafka supports its own Schema-Registy to keep a repository of schemas and version evolution
âś” Salesforce uses both Protocol Buffers (gRPC) and Avro for its Pub/Sub API
gRPC for the underlying message interchange format
Avro for the event payload
✔️ Optimal for internal integrations and controlled microservices
✔️ Perfect when throughput, bandwidth, and/or performance are key
✔️ Keep backwards and forward compatibility through Schema evolution
Image source: Designing Data Intensive Applications, by Martin Kleppmann
By Julián Duque
Exploring protocolos and binary formats in Node.js