Spec Backend Com Golang E Gin • Trilha Progressiva em 4 Níveis


🎯 Nível 1: Fundamentos

Problema 03.1 — Binding de JSON com ShouldBindJSON e Tags de Validação

Contexto: Binding de JSON com ShouldBindJSON e Tags de Validação no contexto de Data Binding e Validação de Structs.

Requisitos de Execução:

  1. Criar struct CriarUsuarioInput com tags binding:'required,email' e fazer bind automático no handler.

Resultado Esperado

Payload inválido rejeitado com 400 Bad Request | Payload válido aceito.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_03_1_SeuNome
  2. Envie na tarefa: Atividade Cap 03 - Data Binding e Validação de Structs
🔑 Gabarito de Código & Solução Comentada
// binding.go
package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

type CriarUsuarioInput struct {
	Nome  string `json:"nome" binding:"required,min=3"`
	Email string `json:"email" binding:"required,email"`
	Idade int    `json:"idade" binding:"gte=18"`
}

func CriarUsuarioHandler(c *gin.Context) {
	var input CriarUsuarioInput
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusCreated, gin.H{"message": "Usuário criado com sucesso", "email": input.Email})
}

🔍 Nível 2: Prática

Problema 03.2 — Binding de Query Parameters e Formulários Multipart

Contexto: Binding de Query Parameters e Formulários Multipart no contexto de Data Binding e Validação de Structs.

Requisitos de Execução:

  1. Fazer bind de parâmetros de busca com c.ShouldBindQuery e upload de imagem com c.FormFile('avatar').

Resultado Esperado

Filtros e arquivo extraídos via binding de formulário.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_03_2_SeuNome
  2. Envie na tarefa: Atividade Cap 03 - Data Binding e Validação de Structs
🔑 Gabarito de Código & Solução Comentada
// form_binding.go
package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

type FiltroBusca struct {
	Termo string `form:"q" binding:"required"`
	Limite int   `form:"limit,default=10"`
}

func BuscarHandler(c *gin.Context) {
	var filtro FiltroBusca
	if err := c.ShouldBindQuery(&filtro); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"erro": err.Error()})
		return
	}
	c.JSON(http.StatusOK, filtro)
}

⚡ Nível 3: Integração

Problema 03.3 — Validador Customizado com go-playground/validator

Contexto: Validador Customizado com go-playground/validator no contexto de Data Binding e Validação de Structs.

Requisitos de Execução:

  1. Registrar função de validação customizada para formato de CPF/CNPJ brasileiro no engine do Gin.

Resultado Esperado

Tag de validação `binding:'valida_cpf'` registrada e validando requisições.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_03_3_SeuNome
  2. Envie na tarefa: Atividade Cap 03 - Data Binding e Validação de Structs
🔑 Gabarito de Código & Solução Comentada
// custom_validation.go
package main

import (
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/validator/v10"
)

var validarCPF validator.Func = func(fl validator.FieldLevel) bool {
	cpf := fl.Field().String()
	return len(cpf) == 11
}

func RegistrarValidadoresCustomizados() {
	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
		v.RegisterValidation("valida_cpf", validarCPF)
	}
}

🏆 Nível 4: Desafio Corporativo

Problema 03.4 — Formatador de Erros de Validação Amigável para Frontend

Contexto: Formatador de Erros de Validação Amigável para Frontend no contexto de Data Binding e Validação de Structs.

Requisitos de Execução:

  1. Mapear erros de validação do tipo validator.ValidationErrors para objeto JSON amigável contendo campo e mensagem.

Resultado Esperado

Erros formatados: [{'campo': 'email', 'mensagem': 'Formato de e-mail inválido'}].

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_03_4_SeuNome
  2. Envie na tarefa: Atividade Cap 03 - Data Binding e Validação de Structs
🔑 Gabarito de Código & Solução Comentada
// error_formatter.go
package main

import (
	"github.com/go-playground/validator/v10"
)

type ErroCampo struct {
	Campo    string `json:"campo"`
	Mensagem string `json:"mensagem"`
}

func FormatarErrosValidacao(err error) []ErroCampo {
	var erros []ErroCampo
	if valErrs, ok := err.(validator.ValidationErrors); ok {
		for _, f := range valErrs {
			erros = append(erros, ErroCampo{
				Campo:    f.Field(),
				Mensagem: "Falha na regra: " + f.Tag(),
			})
		}
	}
	return erros
}