Tratamento de Erros e Validação
Trate a análise do serde como o primeiro portão de segurança - mapeie erros claramente e valide semânticas após o sucesso da sintaxe.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct Input {
#[serde(deserialize_with = "bounded_string")]
name: String,
}
fn bounded_string<'de, D: serde::Deserializer<'de>>(d: D) -> Result<String, D::Error> {
let s = String::deserialize(d)?;
if s.len() > 256 { return Err(serde::de::Error::custom("nome muito longo")); }
Ok(s)
}Quando usar isso: Todas as APIs públicas, webhooks ou endpoints de upload que analisam JSON de clientes não confiáveis.
Exemplo de Trabalho
use serde::Deserialize;
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
struct Signup {
email: String,
age: u8,
}
#[derive(Debug)]
enum ParseError {
Serde(serde_json::Error),
Business(&'static str),
}
fn parse_signup(raw: &str) -> Result<Signup, ParseError> {
let body: Signup = serde_json::from_str(raw).map_err(ParseError::Serde)?;
if !body.email.contains('@') {
return Err(ParseError::Business("email inválido"));
}
if body.age < 18 {
return Err(ParseError::Business("muito jovem"));
}
Ok(body)
}
fn main() {
let ok = parse_signup(r#"{"email":"a@b.co","age":21}"#).unwrap();
assert_eq!(ok.email, "a@b.co");
let extra = parse_signup(r#"{"email":"a@b.co","age":21,"admin":true}"#);
assert!(extra.is_err());
}O que isso demonstra:
deny_unknown_fieldsrejeita chaves JSON inesperadas antecipadamente.- Validação em duas fases: sintaxe serde, depois regras de negócio.
- Tipos de erro distintos para mapeamento de cliente vs. servidor.
Mergulho Profundo
Pipeline de Validação
| Estágio | Verificações |
|---|---|
| Limite de tamanho | Bytes máximos do corpo antes da análise |
| Serde | Tipos, campos obrigatórios, chaves desconhecidas |
| Semântica | E-mail, intervalos, integridade referencial |
| Autorização | Chamador permitido para definir campos |
Notas de Rust
// Mapeia erros serde para HTTP 400
fn bad_request(err: serde_json::Error) -> ApiError {
ApiError::BadRequest(err.to_string())
}Armadilhas
- Apenas validação serde - Aceita e-mails sem sentido sintaticamente válidos. Correção: Adicione validação de domínio após a análise.
- Mensagens de erro para clientes - Erros serde brutos vazam nomes de campos e tipos. Correção: Mapeie para um
códigoestável + mensagem segura. - Sem limite de tamanho - JSON de gigabytes causa OOM antes que o serde seja executado. Correção:
RequestBodyLimitLayerem Axum. - Estouro de inteiro - Números grandes em JSON para
u8falham no serde - bom. Correção: Use larguras apropriadas; documente os limites. - Chaves duplicadas - O comportamento depende do desserializador. Correção:
deny_unknown_fields+ produtores rigorosos.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
crate validator | Regras declarativas de campo | Verificações personalizadas apenas de rede |
| JSON Schema | Aplicação de contrato externo | APIs apenas internas |
garde | Validação em tempo de compilação | Já usa validator |
FAQs
400 vs 422?
400 JSON malformado; 422 JSON válido falhando em regras de negócio - documente o padrão da equipe.
Registrar falhas de análise?
Registre o hash truncado do corpo e o erro, não a carga útil completa de PII.
Desserialização parcial?
serde_json::Value primeiro para sondagem - perde a rigorosidade.
Travessia de caminho em strings?
Valide nomes de arquivos separadamente da análise serde.
Bomba de profundidade aninhada?
Limite a profundidade/recursão JSON no analisador ou rejeite Value aninhado enorme.
Erros do simd-json?
Mesmo padrão de mapeamento - envolva em um tipo de erro de domínio.
Importações em lote?
Colete erros por linha; não falhe o arquivo inteiro em uma linha ruim se o produto permitir.
Protobuf?
Modelo de erro diferente - veja a página gRPC.
Fuzzing?
cargo fuzz nos pontos de entrada de desserialização encontra panics e crashes.
Testes?
Testes de tabela para strings muito longas, campos desconhecidos, incompatibilidades de tipo.
Relacionados
- JSON com serde_json - Funções de análise
- Serialização/Desserialização Personalizada - Validação em linha
- Validação de Requisição - Camada HTTP
- Validação de Entrada e Injeção - Foco em segurança
- Melhores Práticas de Serde - Regras de esquema
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+.