gRPC e Protocol Buffers com Zig

gRPC e Protocol Buffers com Zig

gRPC e Protocol Buffers são o padrão para comunicação eficiente entre microserviços. Embora Zig não tenha suporte nativo a gRPC, a interoperabilidade com C permite usar a biblioteca gRPC C Core, e serialização binária pode ser implementada nativamente em Zig com performance superior.

Serialização Binária em Zig

Antes de gRPC, precisamos serializar dados. Zig permite criar serialização binária compacta e eficiente:

const std = @import("std");

/// Serialização binária compatível com Protocol Buffers (simplificada)
fn Serializer(comptime T: type) type {
    return struct {
        pub fn serializar(valor: T, writer: anytype) !void {
            const info = @typeInfo(T);
            switch (info) {
                .@"struct" => |s| {
                    inline for (s.fields, 1..) |field, tag| {
                        try serializarCampo(tag, @field(valor, field.name), writer);
                    }
                },
                else => @compileError("Tipo não suportado"),
            }
        }

        fn serializarCampo(tag: u32, valor: anytype, writer: anytype) !void {
            const T2 = @TypeOf(valor);
            switch (@typeInfo(T2)) {
                .int => {
                    // Wire type 0: Varint
                    try writer.writeByte(@intCast((tag << 3) | 0));
                    try escreverVarint(writer, @intCast(valor));
                },
                .pointer => |p| {
                    if (p.size == .Slice and p.child == u8) {
                        // Wire type 2: Length-delimited
                        try writer.writeByte(@intCast((tag << 3) | 2));
                        try escreverVarint(writer, valor.len);
                        try writer.writeAll(valor);
                    }
                },
                .bool => {
                    try writer.writeByte(@intCast((tag << 3) | 0));
                    try writer.writeByte(if (valor) 1 else 0);
                },
                else => {},
            }
        }

        fn escreverVarint(writer: anytype, valor: usize) !void {
            var v = valor;
            while (v >= 0x80) {
                try writer.writeByte(@intCast((v & 0x7F) | 0x80));
                v >>= 7;
            }
            try writer.writeByte(@intCast(v));
        }
    };
}

const Pessoa = struct {
    id: u32,
    nome: []const u8,
    email: []const u8,
    ativo: bool,
};

test "serializar Pessoa" {
    var buf: [256]u8 = undefined;
    var stream = std.io.fixedBufferStream(&buf);

    try Serializer(Pessoa).serializar(.{
        .id = 42,
        .nome = "Ana Silva",
        .email = "ana@exemplo.com",
        .ativo = true,
    }, stream.writer());

    const dados = stream.getWritten();
    try std.testing.expect(dados.len > 0);
    try std.testing.expect(dados.len < 50); // Muito compacto
}

gRPC via Interop com C

const c = @cImport({
    @cInclude("grpc/grpc.h");
    @cInclude("grpc/support/time.h");
});

const GrpcServer = struct {
    server: *c.grpc_server,

    pub fn init() !GrpcServer {
        c.grpc_init();
        const server = c.grpc_server_create(null, null) orelse
            return error.ErroGrpc;
        return .{ .server = server };
    }

    pub fn escutar(self: *GrpcServer, endereco: [*:0]const u8) !void {
        const porta = c.grpc_server_add_insecure_http2_port(self.server, endereco);
        if (porta == 0) return error.PortaIndisponivel;
        c.grpc_server_start(self.server);
    }

    pub fn parar(self: *GrpcServer) void {
        c.grpc_server_shutdown_and_notify(self.server, null, null);
        c.grpc_server_destroy(self.server);
        c.grpc_shutdown();
    }
};

Conclusão

gRPC com Zig é possível via interop com a biblioteca C do gRPC, e Zig oferece vantagens para serialização binária personalizada com performance excepcional. Para novos projetos, considere se a serialização binária nativa do Zig não atende suas necessidades sem a complexidade do gRPC.

Conteúdo Relacionado

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.