Validação de dados em Go (Golang): guia completo sobre bibliotecas e abordagens
A validação de dados é uma parte criticamente importante de qualquer aplicação web, API ou microsserviço. Em Go (Golang), esta tarefa é resolvida tanto por meios padrão quanto por poderosas bibliotecas de terceiros. Neste artigo, vamos analisar as principais abordagens, bibliotecas populares e fornecer exemplos práticos de código.
Por que a validação é necessária em Go?
Go é uma linguagem fortemente tipada, o que já oferece alguma proteção contra dados incorretos. No entanto, os tipos não verificam regras de negócio: o email deve conter "@", a idade deve estar na faixa de 0 a 120, a senha deve ter um comprimento mínimo. Sem validação, você corre o risco de obter:
- Injeções SQL e ataques XSS
- Dados incorretos no banco de dados
- Panics inesperados e erros em tempo de execução
Meios de validação integrados
A validação mais simples é feita "manualmente" em funções. Exemplo:
type User struct { Name string Email string Age int}
func ValidateUser(u User) error { if u.Name == "" { return errors.New("name is required") } if !strings.Contains(u.Email, "@") { return errors.New("invalid email") } if u.Age < 0 || u.Age > 150 { return errors.New("age must be between 0 and 150") } return nil}Esta abordagem é simples, mas para estruturas complexas torna-se volumosa e difícil de manter. Por isso, a comunidade Go criou bibliotecas especializadas.
1. go-playground/validator — padrão de facto
Link: github.com/go-playground/validator/v10
Esta é a biblioteca de validação mais popular em Go (mais de 15k estrelas no GitHub). Ela usa tags de struct para descrever regras de forma declarativa.
Instalação
go get github.com/go-playground/validator/v10Exemplo de uso
package main
import ( "fmt" "github.com/go-playground/validator/v10")
type User struct { Name string `validate:"required,min=2,max=50"` Email string `validate:"required,email"` Age int `validate:"gte=0,lte=150"` Password string `validate:"required,min=8"`}
func main() { validate := validator.New()
user := User{ Name: "A", Email: "not-email", Age: 200, Password: "123", }
err := validate.Struct(user) if err != nil { for _, e := range err.(validator.ValidationErrors) { fmt.Printf("Campo: %s, regra: %s, valor: %v", e.Field(), e.Tag(), e.Value()) } }}Saída:
Campo: Name, regra: min, valor: ACampo: Email, regra: email, valor: not-emailCampo: Age, regra: lte, valor: 200Campo: Password, regra: min, valor: 123Tags-regras populares
required— campo obrigatóriomin,max— para números e stringslen— comprimento exatoemail— verificação de emailurl— verificação de URLgte,lte— maior/menor ou igualoneof— um dos valores (oneof=admin user)
Validadores personalizados
validate.RegisterValidation("is-odd", func(fl validator.FieldLevel) bool { return fl.Field().Int()%2 != 0})
type MyStruct struct { Number int `validate:"is-odd"`}2. ozzo-validation — alternativa com encadeamento
Link: github.com/go-ozzo/ozzo-validation/v4
Esta biblioteca oferece uma abordagem mais "Go-idiomática": as regras são definidas através de funções, não de tags. Isso proporciona maior flexibilidade e legibilidade.
Exemplo
package main
import ( "fm Também na biblioteca
Trabalho com XML em Go: encoding/xml, bibliotecas e exemplos
Autorização e Autenticação em Swift: guia completo para iOS/macOS
Quartz Scheduler para Java: guia completo com exemplos práticos
Filas de Tarefas em Rust: Visão Geral das Bibliotecas para Processamento Assíncrono