Skip to content

MessagePack Serialization

MessagePack is a binary serialization format that's more compact and faster than JSON.

Basic Usage

Packing Data

scala
import wvlet.uni.msgpack.spi.MessagePack

// Create a packer
val packer = MessagePack.newPacker()

// Pack primitive values
packer.packString("Alice")
packer.packInt(30)
packer.packBoolean(true)

// Get the bytes
val bytes = packer.toByteArray

Unpacking Data

scala
// Create an unpacker
val unpacker = MessagePack.newUnpacker(bytes)

// Unpack in the same order
val name = unpacker.unpackString()  // "Alice"
val age = unpacker.unpackInt()       // 30
val active = unpacker.unpackBoolean() // true

Packing Complex Structures

Arrays

scala
val packer = MessagePack.newPacker()

// Pack array header with size
packer.packArrayHeader(3)
packer.packInt(1)
packer.packInt(2)
packer.packInt(3)

Maps

scala
val packer = MessagePack.newPacker()

// Pack map header with size
packer.packMapHeader(2)
packer.packString("name")
packer.packString("Alice")
packer.packString("age")
packer.packInt(30)

Unpacking Complex Structures

Arrays

scala
val unpacker = MessagePack.newUnpacker(bytes)

val size = unpacker.unpackArrayHeader()
val items = (0 until size).map(_ => unpacker.unpackInt())

Maps

scala
val unpacker = MessagePack.newUnpacker(bytes)

val size = unpacker.unpackMapHeader()
val map = (0 until size).map { _ =>
  val key = unpacker.unpackString()
  val value = unpacker.unpackInt()
  key -> value
}.toMap

Supported Types

TypePack MethodUnpack Method
BooleanpackBooleanunpackBoolean
IntpackIntunpackInt
LongpackLongunpackLong
FloatpackFloatunpackFloat
DoublepackDoubleunpackDouble
StringpackStringunpackString
BinarypackBinaryHeader + writeunpackBinaryHeader + read
NilpackNilunpackNil

Object Weaving

For automatic serialization of case classes, use ObjectWeaver:

scala
import wvlet.uni.weaver.ObjectWeaver

case class User(name: String, age: Int)

val user = User("Alice", 30)

// Serialize to MessagePack bytes
val bytes = ObjectWeaver.toMsgPack(user)

// Deserialize from bytes
val restored = ObjectWeaver.fromMsgPack[User](bytes)

MessagePack vs JSON

AspectMessagePackJSON
FormatBinaryText
SizeSmallerLarger
SpeedFasterSlower
Human-readableNoYes
SchemaOptionalNone

Use MessagePack when:

  • Performance is critical
  • Bandwidth is limited
  • Human readability isn't needed

Use JSON when:

  • Debugging/logging
  • API responses
  • Configuration files

Best Practices

  1. Match pack/unpack order - Data must be unpacked in the same order it was packed
  2. Include length headers - For arrays and maps
  3. Use ObjectWeaver - For automatic case class serialization
  4. Handle format errors - Wrap unpacking in try-catch

Released under the Apache 2.0 License.