---
title: "Bibliotecas de Serialização em Zig — MessagePack, Protobuf e Mais"
url: "https://ziglang.com.br/ecossistema/bibliotecas-de-serializa%C3%A7%C3%A3o-em-zig-messagepack-protobuf-e-mais/"
markdown_url: "https://ziglang.com.br/ecossistema/bibliotecas-de-serializa%C3%A7%C3%A3o-em-zig-messagepack-protobuf-e-mais.MD"
description: "Guia das bibliotecas de serialização do Zig: MessagePack, Protocol Buffers, CBOR, formatos binários customizados e interoperabilidade."
date: "2026-02-21"
author: "Zig Brasil"
---

# Bibliotecas de Serialização em Zig — MessagePack, Protobuf e Mais

Guia das bibliotecas de serialização do Zig: MessagePack, Protocol Buffers, CBOR, formatos binários customizados e interoperabilidade.


# Bibliotecas de Serialização em Zig — MessagePack, Protobuf e Mais

Serialização eficiente de dados é crucial para comunicação entre serviços, armazenamento e protocolos de rede. O Zig oferece vantagens únicas para serialização: structs packed com layout de memória controlado, comptime para gerar código de serialização automaticamente e interoperabilidade C para usar bibliotecas existentes. Além do [suporte a JSON](/ecossistema/zig-json-libs/) na std, o ecossistema oferece diversas opções binárias.

## Serialização Binária Nativa

O Zig permite serialização direta de structs packed:

```zig
const std = @import("std");

const Mensagem = packed struct {
    tipo: u8,
    flags: u8,
    tamanho: u16,
    timestamp: u64,
    checksum: u32,
};

pub fn serializar(msg: *const Mensagem) [@sizeOf(Mensagem)]u8 {
    return @bitCast(msg.*);
}

pub fn deserializar(bytes: [@sizeOf(Mensagem)]u8) Mensagem {
    return @bitCast(bytes);
}

pub fn enviarPelaRede(stream: std.net.Stream, msg: *const Mensagem) !void {
    const bytes = serializar(msg);
    try stream.writeAll(&bytes);
}

pub fn receberDaRede(stream: std.net.Stream) !Mensagem {
    var bytes: [@sizeOf(Mensagem)]u8 = undefined;
    _ = try stream.readAll(&bytes);
    return deserializar(bytes);
}
```

## MessagePack

O MessagePack é um formato binário compacto e rápido, ideal para comunicação entre serviços:

```zig
const msgpack = @import("zig-msgpack");

const Produto = struct {
    id: u64,
    nome: []const u8,
    preco: f64,
    tags: []const []const u8,
};

pub fn main() !void {
    const allocator = std.heap.page_allocator;

    const produto = Produto{
        .id = 42,
        .nome = "Widget Premium",
        .preco = 99.90,
        .tags = &.{ "eletrônicos", "premium" },
    };

    // Serializar
    var buf: [1024]u8 = undefined;
    const encoded = try msgpack.encode(Produto, &buf, produto);

    // Deserializar
    const decoded = try msgpack.decode(Produto, allocator, encoded);
    std.debug.print("Produto: {s} - R${d:.2}\n", .{ decoded.nome, decoded.preco });
}
```

## Protocol Buffers

### zig-protobuf

```zig
const protobuf = @import("zig-protobuf");

// Gerado a partir de .proto
const Usuario = protobuf.Message(struct {
    id: u64 = 0,       // field 1
    nome: []const u8 = "",  // field 2
    email: []const u8 = "", // field 3
    idade: u32 = 0,     // field 4
});

pub fn main() !void {
    const allocator = std.heap.page_allocator;

    // Criar mensagem
    var usuario = Usuario{
        .id = 1,
        .nome = "Maria",
        .email = "maria@exemplo.com",
        .idade = 28,
    };

    // Serializar
    var buf: [256]u8 = undefined;
    const tamanho = try usuario.encode(&buf);

    // Deserializar
    const decoded = try Usuario.decode(allocator, buf[0..tamanho]);
    std.debug.print("Usuário: {s}\n", .{decoded.nome});
}
```

## CBOR

O CBOR (Concise Binary Object Representation) é um formato binário baseado no modelo de dados JSON:

```zig
const cbor = @import("zig-cbor");

pub fn main() !void {
    const allocator = std.heap.page_allocator;

    // Serializar para CBOR
    var buf: [1024]u8 = undefined;
    var encoder = cbor.Encoder.init(&buf);

    try encoder.encodeMapHeader(3);
    try encoder.encodeString("nome");
    try encoder.encodeString("João");
    try encoder.encodeString("idade");
    try encoder.encodeUint(30);
    try encoder.encodeString("ativo");
    try encoder.encodeBool(true);

    const encoded = encoder.getWritten();

    // Deserializar
    var decoder = cbor.Decoder.init(encoded, allocator);
    const valor = try decoder.decode();
    _ = valor;
}
```

## Serialização com Comptime

Uma das vantagens mais poderosas do Zig é gerar serializadores em comptime:

```zig
fn AutoSerializer(comptime T: type) type {
    return struct {
        pub fn serialize(value: T, writer: anytype) !void {
            const info = @typeInfo(T);
            switch (info) {
                .Struct => |s| {
                    inline for (s.fields) |field| {
                        try serializeField(field.type, @field(value, field.name), writer);
                    }
                },
                else => @compileError("Tipo não suportado: " ++ @typeName(T)),
            }
        }

        fn serializeField(comptime FieldType: type, value: FieldType, writer: anytype) !void {
            switch (@typeInfo(FieldType)) {
                .Int => try writer.writeInt(FieldType, value, .little),
                .Float => {
                    const IntType = std.meta.Int(.unsigned, @bitSizeOf(FieldType));
                    try writer.writeInt(IntType, @bitCast(value), .little);
                },
                .Bool => try writer.writeByte(if (value) 1 else 0),
                .Pointer => |ptr| {
                    if (ptr.size == .Slice) {
                        try writer.writeInt(u32, @intCast(value.len), .little);
                        try writer.writeAll(value);
                    }
                },
                else => {},
            }
        }

        pub fn deserialize(reader: anytype, allocator: std.mem.Allocator) !T {
            var result: T = undefined;
            const info = @typeInfo(T);
            inline for (info.Struct.fields) |field| {
                @field(result, field.name) = try deserializeField(
                    field.type, reader, allocator,
                );
            }
            return result;
        }

        fn deserializeField(comptime FieldType: type, reader: anytype, allocator: std.mem.Allocator) !FieldType {
            _ = allocator;
            switch (@typeInfo(FieldType)) {
                .Int => return try reader.readInt(FieldType, .little),
                .Float => {
                    const IntType = std.meta.Int(.unsigned, @bitSizeOf(FieldType));
                    const bits = try reader.readInt(IntType, .little);
                    return @bitCast(bits);
                },
                .Bool => return (try reader.readByte()) != 0,
                else => return undefined,
            }
        }
    };
}

// Uso
const MeuDado = struct {
    id: u32,
    valor: f64,
    ativo: bool,
};

const Serializer = AutoSerializer(MeuDado);

test "serialização automática" {
    var buf: [256]u8 = undefined;
    var stream = std.io.fixedBufferStream(&buf);

    const original = MeuDado{ .id = 42, .valor = 3.14, .ativo = true };
    try Serializer.serialize(original, stream.writer());

    stream.pos = 0;
    const restaurado = try Serializer.deserialize(stream.reader(), std.testing.allocator);

    try std.testing.expectEqual(original.id, restaurado.id);
}
```

## Comparação de Formatos

| Formato | Tamanho | Velocidade | Schema | Legível | Uso Ideal |
|---|---|---|---|---|---|
| JSON | Grande | Média | Não | Sim | APIs web, config |
| MessagePack | Pequeno | Rápida | Não | Não | RPC, cache |
| Protobuf | Pequeno | Rápida | Sim | Não | gRPC, microserviços |
| CBOR | Pequeno | Rápida | Não | Não | IoT, COSE |
| Packed struct | Mínimo | Máxima | Implícito | Não | Protocolos internos |
| FlatBuffers | Médio | Máxima | Sim | Não | Jogos, mobile |

## Boas Práticas

1. **Escolha o formato pelo caso de uso**: JSON para interop, MessagePack para performance, Protobuf para evolução de schema
2. **Versione seus formatos**: Adicione campos de versão para compatibilidade futura
3. **Valide após deserialização**: Verifique invariantes dos dados
4. **Use comptime**: Gere serializadores automaticamente para reduzir código manual
5. **Considere endianness**: Use little-endian para x86/ARM, big-endian para rede

## Próximos Passos

Explore as [bibliotecas JSON](/ecossistema/zig-json-libs/) para serialização textual, as [bibliotecas de compressão](/ecossistema/zig-compression-libs/) para otimizar tamanho, e as [bibliotecas de rede](/ecossistema/zig-network/) para transmissão eficiente. Consulte nossos [tutoriais](/tutoriais/) para projetos práticos.
