Melhores Práticas do Serde
Regras para schemas de serialização estáveis, versionados e compatíveis com versões futuras em serviços Rust de produção.
Como Usar Esta Lista
- Aplique ao projetar APIs públicas, barramentos de eventos e blobs persistidos.
- Adicione testes de snapshot em CI para cada alteração de schema.
- Trate alterações de wirebreaking como migrações de banco de dados.
A - Design de Schema
- Prefira tags de enum explícitas em JSON público. Evite
untaggedpara APIs externas. - Use
#[serde(default)]em novos campos opcionais. Clientes antigos podem omiti-los. - Adicione o campo
versiona blobs persistidos. Migre leitores explicitamente. - Separe DTOs de API de modelos de domínio quando as formas divergem. Não exponha nomes internos.
- Documente a semântica de nulo vs. ausente.
Optionpula vs.nullexplícito afeta clientes.
B - Compatibilidade
- Nunca remova ou renomeie campos sem um aumento de versão. Use
aliaspara renomeações durante a transição. -
deny_unknown_fieldsem dados de entrada não confiáveis. Rejeite chaves surpresa. - Faça snapshot do JSON para cada variante de enum. Capture regressões de tagging em CI.
- Teste o round-trip para cada formato de wire que você envia. JSON != layout bincode.
- Mantenha a variante
#[serde(other)]para tipos de evento desconhecidos. Consumidores compatíveis com versões futuras.
C - Desempenho e Segurança
- Limite o tamanho do corpo da requisição antes da desserialização. Limite de corpo Tower ou verificação manual.
- Use
&stremprestado apenas quando o buffer sobreviver ao valor. Padrão paraStringem manipuladores. - Evite
serde_json::Valuepara caminhos críticos. Structs tipadas ou streaming. - Limite os tamanhos de coleção em desserializadores personalizados. Previne bombas de alocação.
- Não use
unwrapem resultados de parse em entrada não confiável. Mapeie para erros tipados.
D - Operações
- Registre falhas do serde sem o payload completo. Hash ou trunque para GDPR.
- Fixe crates serde e de formato no workspace. Builds reproduzíveis.
- Use feature gates para formatos opcionais. Binários menores quando apenas JSON é necessário.
- Alinhe OpenAPI/Protobuf com tipos serde. Fonte única de verdade sempre que possível.
- Execute
cargo fuzznos pontos de entrada de decodificação. Encontre panics antes dos atacantes.
FAQs
Maior erro do serde?
Quebrar a compatibilidade do wire sem campo de versão ou caminho de upgrade do consumidor.
Proliferação de DTOs?
Aceitável nas fronteiras da API - mais barato do que quebrar clientes móveis.
Política camelCase?
rename_all = "camelCase" em todos os DTOs JSON externos - consistente uma vez escolhido.
bincode em DB?
Apenas se os leitores forem exclusivamente Rust; prefixo de versão obrigatório.
Campos secretos?
#[serde(skip_serializing)] em segredos; nunca desserialize segredos de entrada de clientes.
Formato de Timestamp?
Strings RFC 3339 via serde_with ou módulo with customizado - documente o fuso horário.
Inteiros grandes?
Codifique IDs u64 como string em JSON para interoperabilidade com JavaScript, se necessário.
Listas polimórficas?
Array de enum com tag interna - faça snapshot de cada variante.
Arquivos de configuração?
TOML para edição humana; deny_unknown_fields rigoroso ao carregar.
Teste mínimo?
Round-trip + rejeição de campo desconhecido + um fixture de payload legado.
Relacionados
- Noções Básicas do Serde - Fundamentos
- Enums e Tagging - Formatos de Wire
- Tratamento de Erros e Validação - Entrada não confiável
- Noções Básicas de Design de API - Contratos HTTP
- Melhores Práticas de Backends Web - Camada de serviço
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.