---
title: "Como Parsear JSON em Zig"
url: "https://ziglang.com.br/receitas/como-parsear-json-em-zig/"
markdown_url: "https://ziglang.com.br/receitas/como-parsear-json-em-zig.MD"
description: "Aprenda a parsear e deserializar dados JSON em Zig usando std.json, incluindo parsing tipado, dinâmico e tratamento de campos opcionais e aninhados."
date: "2026-02-21"
author: "Zig Brasil"
---

# Como Parsear JSON em Zig

Aprenda a parsear e deserializar dados JSON em Zig usando std.json, incluindo parsing tipado, dinâmico e tratamento de campos opcionais e aninhados.


## Introdução

JSON (JavaScript Object Notation) é o formato de dados mais usado para APIs web, configuração e troca de dados entre sistemas. Em Zig, a biblioteca padrão `std.json` oferece ferramentas poderosas para parsear JSON de forma tipada ou dinâmica.

Nesta receita, você aprenderá as diversas formas de parsear JSON em Zig, desde parsing simples até cenários complexos com dados aninhados.

## Pré-requisitos

- Zig instalado (versão 0.13+). Veja o [guia de instalação](/tutoriais/como-instalar-zig/)
- Conhecimento básico de Zig. Consulte a [introdução ao Zig](/tutoriais/introducao-ao-zig/)
- Familiaridade com [structs e enums](/tutoriais/structs-enums-unions-zig/)

## Parsing Tipado (Recomendado)

A forma mais segura: defina uma struct que espelha o JSON esperado:

```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 json_str =
        \\{
        \\  "nome": "Maria Silva",
        \\  "email": "maria@exemplo.com",
        \\  "idade": 28,
        \\  "ativo": true
        \\}
    ;

    const parsed = try std.json.parseFromSlice(
        Usuario,
        allocator,
        json_str,
        .{},
    );
    defer parsed.deinit();

    const user = parsed.value;
    std.debug.print("Nome: {s}\n", .{user.nome});
    std.debug.print("Email: {s}\n", .{user.email});
    std.debug.print("Idade: {d}\n", .{user.idade});
    std.debug.print("Ativo: {}\n", .{user.ativo});
}
```

### Saída esperada

```
Nome: Maria Silva
Email: maria@exemplo.com
Idade: 28
Ativo: true
```

## Parsing com Campos Opcionais

Use tipos opcionais para campos que podem não existir no JSON:

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

const Produto = struct {
    nome: []const u8,
    preco: f64,
    descricao: ?[]const u8 = null,
    estoque: ?u32 = null,
    tags: ?[]const []const u8 = null,
};

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

    // JSON sem campos opcionais
    const json_minimal =
        \\{"nome": "Teclado Mecânico", "preco": 299.90}
    ;

    const p1 = try std.json.parseFromSlice(Produto, allocator, json_minimal, .{
        .ignore_unknown_fields = true,
    });
    defer p1.deinit();

    std.debug.print("Produto: {s}\n", .{p1.value.nome});
    std.debug.print("Preço: {d:.2}\n", .{p1.value.preco});
    std.debug.print("Descrição: {s}\n", .{p1.value.descricao orelse "N/A"});

    // JSON completo
    const json_full =
        \\{
        \\  "nome": "Mouse Gamer",
        \\  "preco": 159.90,
        \\  "descricao": "Mouse com 6 botões programáveis",
        \\  "estoque": 42,
        \\  "tags": ["gamer", "periférico", "rgb"]
        \\}
    ;

    const p2 = try std.json.parseFromSlice(Produto, allocator, json_full, .{
        .ignore_unknown_fields = true,
    });
    defer p2.deinit();

    std.debug.print("\nProduto: {s}\n", .{p2.value.nome});
    std.debug.print("Descrição: {s}\n", .{p2.value.descricao.?});
    std.debug.print("Estoque: {d}\n", .{p2.value.estoque.?});
    if (p2.value.tags) |tags| {
        std.debug.print("Tags: ", .{});
        for (tags, 0..) |tag, i| {
            if (i > 0) std.debug.print(", ", .{});
            std.debug.print("{s}", .{tag});
        }
        std.debug.print("\n", .{});
    }
}
```

## Parsing com Ignorar Campos Desconhecidos

Quando o JSON contém campos que você não precisa:

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

const Resumo = struct {
    id: u64,
    titulo: []const u8,
};

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

    // JSON com muitos campos que não precisamos
    const json_str =
        \\{
        \\  "id": 12345,
        \\  "titulo": "Artigo sobre Zig",
        \\  "autor": "João",
        \\  "data_publicacao": "2026-02-21",
        \\  "conteudo": "Lorem ipsum...",
        \\  "comentarios": 42,
        \\  "visualizacoes": 1500
        \\}
    ;

    // ignore_unknown_fields permite ignorar campos extras
    const parsed = try std.json.parseFromSlice(Resumo, allocator, json_str, .{
        .ignore_unknown_fields = true,
    });
    defer parsed.deinit();

    std.debug.print("ID: {d}\n", .{parsed.value.id});
    std.debug.print("Título: {s}\n", .{parsed.value.titulo});
}
```

## Parsing Dinâmico (sem tipo)

Quando a estrutura JSON é desconhecida em tempo de compilação:

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

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

    const json_str =
        \\{
        \\  "nome": "Zig Brasil",
        \\  "membros": 1500,
        \\  "ativo": true,
        \\  "linguagens": ["zig", "c", "c++"],
        \\  "contato": {
        \\    "email": "contato@zigbrasil.com",
        \\    "site": "https://zigbrasil.com"
        \\  }
        \\}
    ;

    const parsed = try std.json.parseFromSlice(
        std.json.Value,
        allocator,
        json_str,
        .{},
    );
    defer parsed.deinit();

    const root = parsed.value.object;

    // Acessar string
    const nome = root.get("nome").?.string;
    std.debug.print("Nome: {s}\n", .{nome});

    // Acessar número
    const membros = root.get("membros").?.integer;
    std.debug.print("Membros: {d}\n", .{membros});

    // Acessar boolean
    const ativo = root.get("ativo").?.bool;
    std.debug.print("Ativo: {}\n", .{ativo});

    // Acessar array
    const linguagens = root.get("linguagens").?.array;
    std.debug.print("Linguagens: ", .{});
    for (linguagens.items, 0..) |item, i| {
        if (i > 0) std.debug.print(", ", .{});
        std.debug.print("{s}", .{item.string});
    }
    std.debug.print("\n", .{});

    // Acessar objeto aninhado
    const contato = root.get("contato").?.object;
    const email = contato.get("email").?.string;
    std.debug.print("Email: {s}\n", .{email});
}
```

## Parsing de Array JSON

Parsear um array de objetos:

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

const Tarefa = struct {
    id: u64,
    titulo: []const u8,
    completa: bool,
};

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

    const json_str =
        \\[
        \\  {"id": 1, "titulo": "Estudar Zig", "completa": true},
        \\  {"id": 2, "titulo": "Criar projeto", "completa": false},
        \\  {"id": 3, "titulo": "Escrever testes", "completa": false}
        \\]
    ;

    const parsed = try std.json.parseFromSlice(
        []Tarefa,
        allocator,
        json_str,
        .{},
    );
    defer parsed.deinit();

    const tarefas = parsed.value;
    std.debug.print("Total de tarefas: {d}\n\n", .{tarefas.len});

    for (tarefas) |tarefa| {
        const status = if (tarefa.completa) "[x]" else "[ ]";
        std.debug.print("{s} #{d}: {s}\n", .{ status, tarefa.id, tarefa.titulo });
    }
}
```

### Saída esperada

```
Total de tarefas: 3

[x] #1: Estudar Zig
[ ] #2: Criar projeto
[ ] #3: Escrever testes
```

## Tratamento de Erros no Parsing

Trate erros de JSON malformado:

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

const Config = struct {
    porta: u16,
    host: []const u8,
};

fn parseConfig(allocator: std.mem.Allocator, json_str: []const u8) !Config {
    const parsed = std.json.parseFromSlice(Config, allocator, json_str, .{}) catch |err| {
        switch (err) {
            error.UnexpectedCharacter => {
                std.debug.print("Erro: JSON contém caractere inesperado\n", .{});
                return err;
            },
            error.InvalidNumber => {
                std.debug.print("Erro: número inválido no JSON\n", .{});
                return err;
            },
            else => {
                std.debug.print("Erro ao parsear JSON: {}\n", .{err});
                return err;
            },
        }
    };
    defer parsed.deinit();

    // Copiar strings para que sobrevivam após deinit
    const host = try allocator.dupe(u8, parsed.value.host);

    return Config{
        .porta = parsed.value.porta,
        .host = host,
    };
}

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

    // JSON válido
    const valid = try parseConfig(allocator, "{\"porta\": 8080, \"host\": \"localhost\"}");
    defer allocator.free(valid.host);
    std.debug.print("Config: {s}:{d}\n", .{ valid.host, valid.porta });

    // JSON inválido
    _ = parseConfig(allocator, "{porta: 8080}") catch {
        std.debug.print("Falha ao parsear JSON inválido (esperado)\n", .{});
    };
}
```

## Dicas e Boas Práticas

1. **Prefira parsing tipado**: Use structs quando a estrutura é conhecida. É mais seguro e performático.

2. **Use `ignore_unknown_fields`**: Ao consumir APIs externas, ignore campos que você não precisa.

3. **Campos opcionais com valor padrão**: Use `?T = null` para campos que podem não existir.

4. **Libere memória**: Sempre chame `parsed.deinit()` para liberar a memória alocada pelo parser.

5. **Cuidado com strings**: As strings do JSON parseado são referências ao buffer original ou à memória do parsed. Use `allocator.dupe` se precisar mantê-las após `deinit()`.

## Receitas Relacionadas

- [Como gerar JSON em Zig](/receitas/zig-gerar-json/) - Serializar dados para JSON
- [Como ler/escrever JSON em arquivos](/receitas/zig-json-arquivo/) - Persistência de JSON
- [Como fazer streaming de JSON em Zig](/receitas/zig-json-stream/) - Parsing eficiente
- [Como validar JSON em Zig](/receitas/zig-json-validar/) - Validação de dados
- [Como fazer requisições HTTP GET em Zig](/receitas/zig-http-get-request/) - Consumir APIs

## Tutoriais Relacionados

- [Parsing JSON em Zig](/tutoriais/parsing-json-zig/)
- [Structs, Enums e Unions em Zig](/tutoriais/structs-enums-unions-zig/)
- [Gerenciamento de Memória em Zig](/tutoriais/gerenciamento-de-memoria-zig/)
