Implementing Data Serialization

1. Understanding Serialization Formats

FormatTypeSchemaSizeUse Case
JSONTextNoneLargeWeb APIs, debugging
XMLTextXSD optionalLargestLegacy, SOAP
YAMLTextNoneLargeConfig files
ProtobufBinaryRequired (.proto)CompactgRPC, microservices
AvroBinaryRequired (JSON)CompactKafka, Hadoop
ThriftBinaryRequired (.thrift)CompactCross-language RPC
MessagePackBinarySchemalessCompactJSON drop-in
CBORBinarySchemalessCompactIoT, COSE
FlatBuffersBinaryRequiredZero-copyGames, latency-critical

2. Working with Protocol Buffers (protobuf)

Example: protobuf schema and Java usage

syntax = "proto3";
package orders;

message Order {
  string id = 1;
  string customer_id = 2;
  repeated LineItem items = 3;
  int64 created_at_ms = 4;
}

message LineItem {
  string sku = 1;
  int32 quantity = 2;
  double price = 3;
}
Order order = Order.newBuilder()
    .setId("o-42")
    .setCustomerId("c-7")
    .addItems(LineItem.newBuilder().setSku("A1").setQuantity(2).setPrice(9.99))
    .setCreatedAtMs(System.currentTimeMillis())
    .build();

byte[] bytes = order.toByteArray();
Order parsed = Order.parseFrom(bytes);
FeatureDetail
Wire formatTag-length-value, varint encoding
Field tags1-15 = 1 byte; reserve low tags for hot fields
Forward compatUnknown fields preserved (proto3.5+)
LanguagesJava, Go, Python, C++, Rust, JS, Kotlin, Swift, etc.

3. Working with Apache Avro

FeatureDetail
SchemaJSON, embedded in file or referenced from registry
Reader/Writer schemasResolution rules enable evolution
EncodingBinary or JSON
Best forLong-term data lake storage, Kafka payloads

Example: Avro schema

{
  "type": "record",
  "name": "Order",
  "namespace": "com.shop",
  "fields": [
    { "name": "id", "type": "string" },
    { "name": "amount", "type": "double" },
    { "name": "currency", "type": "string", "default": "USD" }
  ]
}

4. Working with Apache Thrift

FeatureDetail
IDL.thrift files define structs & services
TransportsTSocket, TFramedTransport, THttpTransport
ProtocolsTBinary, TCompact, TJSON
OriginFacebook, used by Cassandra, HBase

5. Implementing Binary Serialization (MessagePack)

FeatureDetail
SchemaSchemaless (like JSON)
Size~30-50% smaller than JSON
SpeedFaster parse/serialize than JSON
Use CaseRedis (RESP3), Fluentd, mobile APIs

6. Implementing Schema Evolution

ChangeProtobufAvro
Add optional fieldSafeSafe (with default)
Remove fieldReserve tagReader uses default
Rename fieldTag preserves identityUse aliases
Change typeLimited (int↔long)Promotion rules
Required → optionalN/A in proto3Add default

7. Implementing Forward and Backward Compatibility

DirectionMeaningStrategy
BackwardNew code reads old dataDefaults for new fields
ForwardOld code reads new dataIgnore unknown fields
FullBoth directionsRequired for rolling upgrades

8. Working with Schema Registry

FeatureDetail
PurposeCentralized versioned schemas referenced by ID
Wire format[magic byte][schema id][payload]
Compatibility modesBACKWARD, FORWARD, FULL, NONE
ToolsConfluent Schema Registry, AWS Glue, Apicurio

9. Understanding Serialization Performance Trade-offs

FormatEncode (MB/s)Decode (MB/s)Size
JSON~200~1501.0× (baseline)
Protobuf~700~9000.3-0.5×
Avro~500~6000.3-0.5×
FlatBuffers~1500~5000 (zero-copy)0.5-0.7×
MessagePack~400~5000.5-0.7×
Note: Numbers are order-of-magnitude only; benchmark with your payload shape.

10. Handling Schema Versioning

StrategyMechanism
Embedded versionField schema_version in payload
Registry IDSchema ID in wire format header
Topic-per-versionKafka orders-v1, orders-v2
Dual writeProducer writes both during migration