---
title: "Como Gerar e Serializar JSON em Zig"
url: "https://ziglang.com.br/receitas/como-gerar-e-serializar-json-em-zig/"
markdown_url: "https://ziglang.com.br/receitas/como-gerar-e-serializar-json-em-zig.MD"
description: "Aprenda a gerar e serializar dados para JSON em Zig usando std.json.stringify, incluindo formatação, structs aninhadas e arrays de objetos."
date: "2026-02-21"
author: "Zig Brasil"
---

# Como Gerar e Serializar JSON em Zig

Aprenda a gerar e serializar dados para JSON em Zig usando std.json.stringify, incluindo formatação, structs aninhadas e arrays de objetos.


## Introdução

Gerar JSON é tão importante quanto parseá-lo. Seja para responder a uma API, salvar configurações ou exportar dados, a serialização JSON é uma operação fundamental. Em Zig, `std.json.stringify` e `std.json.stringifyAlloc` permitem converter structs e valores Zig diretamente para JSON.

Nesta receita, você aprenderá a serializar diferentes tipos de dados para JSON.

## Pré-requisitos

- Zig instalado (versão 0.13+). Veja o [guia de instalação](/tutoriais/como-instalar-zig/)
- Conhecimento de [parsing JSON](/receitas/zig-parse-json/) em Zig

## Serializar uma Struct Simples

Converta uma struct Zig diretamente para JSON:

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

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

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const usuario = Usuario{
        .nome = "Maria Silva",
        .email = "maria@exemplo.com",
        .idade = 28,
        .ativo = true,
    };

    // Serializar para string alocada
    const json = try std.json.stringifyAlloc(allocator, usuario, .{});
    defer allocator.free(json);

    std.debug.print("{s}\n", .{json});
}
```

### Saída esperada

```json
{"nome":"Maria Silva","email":"maria@exemplo.com","idade":28,"ativo":true}
```

## JSON Formatado (Pretty Print)

Para JSON legível com indentação:

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

const Configuracao = struct {
    servidor: struct {
        host: []const u8,
        porta: u16,
    },
    banco_dados: struct {
        url: []const u8,
        pool_size: u32,
    },
    debug: bool,
};

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const config = Configuracao{
        .servidor = .{
            .host = "0.0.0.0",
            .porta = 8080,
        },
        .banco_dados = .{
            .url = "postgresql://localhost:5432/meubanco",
            .pool_size = 10,
        },
        .debug = false,
    };

    // Serializar com formatação (indentação de 4 espaços)
    const json = try std.json.stringifyAlloc(allocator, config, .{
        .whitespace = .indent_4,
    });
    defer allocator.free(json);

    std.debug.print("{s}\n", .{json});
}
```

### Saída esperada

```json
{
    "servidor": {
        "host": "0.0.0.0",
        "porta": 8080
    },
    "banco_dados": {
        "url": "postgresql://localhost:5432/meubanco",
        "pool_size": 10
    },
    "debug": false
}
```

## Serializar para um Writer

Escreva JSON diretamente para qualquer writer (arquivo, buffer, rede):

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

const Evento = struct {
    tipo: []const u8,
    timestamp: i64,
    dados: []const u8,
};

pub fn main() !void {
    const evento = Evento{
        .tipo = "login",
        .timestamp = 1740100000,
        .dados = "usuario=maria",
    };

    // Escrever para stdout
    const stdout = std.io.getStdOut().writer();
    try std.json.stringify(evento, .{}, stdout);
    try stdout.writeByte('\n');

    // Escrever para buffer fixo
    var buffer: [256]u8 = undefined;
    var stream = std.io.fixedBufferStream(&buffer);
    try std.json.stringify(evento, .{}, stream.writer());

    const json = stream.getWritten();
    std.debug.print("Buffer: {s}\n", .{json});
}
```

## Serializar Arrays e Slices

Arrays e slices são automaticamente convertidos para arrays JSON:

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

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

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const produtos = [_]Produto{
        .{
            .id = 1,
            .nome = "Notebook",
            .preco = 4599.90,
            .tags = &.{ "eletrônico", "computador" },
        },
        .{
            .id = 2,
            .nome = "Teclado",
            .preco = 299.90,
            .tags = &.{ "periférico", "acessório" },
        },
        .{
            .id = 3,
            .nome = "Monitor",
            .preco = 1899.90,
            .tags = &.{ "eletrônico", "display" },
        },
    };

    const json = try std.json.stringifyAlloc(allocator, &produtos, .{
        .whitespace = .indent_2,
    });
    defer allocator.free(json);

    std.debug.print("{s}\n", .{json});
}
```

## Campos Opcionais (null em JSON)

Campos opcionais `?T` são serializados como `null` quando não tem valor:

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

const Perfil = struct {
    nome: []const u8,
    bio: ?[]const u8,
    site: ?[]const u8,
    seguidores: ?u32,
};

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Perfil completo
    const perfil_completo = Perfil{
        .nome = "João Dev",
        .bio = "Desenvolvedor Zig apaixonado",
        .site = "https://joaodev.com",
        .seguidores = 1500,
    };

    const json1 = try std.json.stringifyAlloc(allocator, perfil_completo, .{
        .whitespace = .indent_2,
    });
    defer allocator.free(json1);
    std.debug.print("Completo:\n{s}\n\n", .{json1});

    // Perfil mínimo (campos opcionais como null)
    const perfil_minimo = Perfil{
        .nome = "Ana",
        .bio = null,
        .site = null,
        .seguidores = null,
    };

    const json2 = try std.json.stringifyAlloc(allocator, perfil_minimo, .{
        .whitespace = .indent_2,
    });
    defer allocator.free(json2);
    std.debug.print("Mínimo:\n{s}\n", .{json2});
}
```

### Saída esperada

```json
Completo:
{
  "nome": "João Dev",
  "bio": "Desenvolvedor Zig apaixonado",
  "site": "https://joaodev.com",
  "seguidores": 1500
}

Mínimo:
{
  "nome": "Ana",
  "bio": null,
  "site": null,
  "seguidores": null
}
```

## Construir JSON Dinamicamente

Para JSON com estrutura dinâmica, use `std.json.Value`:

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

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Criar objeto JSON dinamicamente
    var root = std.json.Value{ .object = std.json.ObjectMap.init(allocator) };
    defer root.object.deinit();

    try root.object.put("versao", .{ .string = "1.0.0" });
    try root.object.put("nome", .{ .string = "meu-app" });
    try root.object.put("porta", .{ .integer = 3000 });

    // Criar sub-objeto
    var deps = std.json.ObjectMap.init(allocator);
    defer deps.deinit();
    try deps.put("std", .{ .string = "0.13.0" });
    try root.object.put("dependencias", .{ .object = deps });

    // Serializar
    const json = try std.json.stringifyAlloc(allocator, root, .{
        .whitespace = .indent_2,
    });
    defer allocator.free(json);

    std.debug.print("{s}\n", .{json});
}
```

## Dicas e Boas Práticas

1. **Use structs para JSON estático**: Quando a estrutura é conhecida, structs são mais eficientes e seguras.

2. **Escolha a formatação**: Use `.whitespace = .indent_2` ou `.indent_4` para arquivos de configuração legíveis. Sem whitespace para dados de rede.

3. **Writers para streaming**: Use `std.json.stringify` com um writer para evitar alocações grandes.

4. **Campos opcionais**: Use `?T` para campos que podem ser `null` no JSON.

5. **Combine com HTTP**: Use a serialização para enviar dados via [HTTP POST](/receitas/zig-http-post-request/).

## Receitas Relacionadas

- [Como parsear JSON em Zig](/receitas/zig-parse-json/) - Operação inversa
- [Como ler/escrever JSON em arquivos](/receitas/zig-json-arquivo/) - Persistência
- [Como validar JSON em Zig](/receitas/zig-json-validar/) - Validação
- [Como fazer requisições HTTP POST em Zig](/receitas/zig-http-post-request/) - Enviar JSON via HTTP

## Tutoriais Relacionados

- [Parsing JSON em Zig](/tutoriais/parsing-json-zig/)
- [Structs, Enums e Unions em Zig](/tutoriais/structs-enums-unions-zig/)
