🚀 Capítulo 18: O Transportador (Tema: Carga Explosiva)
NOTE
Este capítulo utiliza a temática do filme Carga Explosiva (The Transporter) para explicar o Upload de Arquivos no Gin. Aprenda a receber imagens e arquivos pesados na sua API com segurança!
1. 🎯 Objetivo da Aula
Compreender como receber arquivos e imagens enviados pelo usuário através de requisições HTTP do tipo multipart/form-data usando o framework Gin e como salvá-los no servidor.
2. 🏢 O Cenário Prático (Seu Desafio)
No filme de ação Carga Explosiva, o motorista profissional Frank Martin possui regras muito rígidas para transportar qualquer mercadoria perigosa: “1. Nunca mude o trato; 2. Sem nomes; 3. Nunca abra a encomenda”. Ele recebe a carga misteriosa, garante que ela chegue intacta ao destino e a entrega com precisão cirúrgica.
No desenvolvimento de APIs, muitas vezes o usuário precisa enviar mais do que apenas textos simples em formato JSON. Ele precisa enviar “cargas pesadas”: uma foto de perfil, um PDF de currículo ou o comprovante de um pagamento!
- O protocolo HTTP usa um formato especial chamado
multipart/form-datapara empacotar esses arquivos binários e enviá-los pela rede. - O framework Gin possui ferramentas específicas para receber essa “encomenda”, verificar o tamanho dela e salvá-la na pasta correta do servidor. Seu desafio é ser o transportador!
🧠 Fundamentos: A Teoria Traduzida
📦 1. Recebendo o Arquivo:
No Gin, nós não usamos o ShouldBindJSON para arquivos. Nós usamos o método c.FormFile() passando o nome do campo que o usuário usou no formulário.
r.POST("/upload", func(c *gin.Context) {
// Captura o arquivo da requisição
file, err := c.FormFile("foto")
if err != nil {
c.JSON(400, gin.H{"erro": "Nenhum arquivo enviado!"})
return
}
// Mostra o nome do arquivo recebido
fmt.Println("Arquivo recebido:", file.Filename)
})💾 2. Salvando a Encomenda:
Depois de receber o arquivo na memória, nós precisamos salvá-lo em uma pasta física do nosso servidor usando o comando c.SaveUploadedFile():
c.SaveUploadedFile(file, "uploads/" + file.Filename)4. 📖 Exemplo Guiado: O Código do Transportador
Veja como criar uma rota completa de upload de imagens:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// Rota que recebe a carga
r.POST("/encomenda", func(c *gin.Context) {
file, err := c.FormFile("carga")
if err != nil {
c.JSON(400, gin.H{"status": "Trato quebrado! Sem arquivo."})
return
}
// Salva o arquivo na pasta 'destino'
c.SaveUploadedFile(file, "destino/" + file.Filename)
c.JSON(200, gin.H{"status": "Carga entregue com sucesso!"})
})
r.Run(":8080")
}5. 🛠️ Prática Obrigatória 1: Capturando o Arquivo
Imagine que você está criando uma rota para o usuário enviar o currículo em PDF e o campo no formulário se chama "curriculo".
- Qual linha de código Go você deve escrever para capturar esse arquivo da requisição do Gin?
6. 🛠️ Prática Obrigatória 2: O Formato dos Dados
- Por que nós não podemos usar o formato JSON tradicional quando queremos enviar uma foto ou um arquivo PDF do nosso aplicativo para a nossa API? Qual formato devemos usar?
7. 📤 Instruções de Entrega (GitHub Desktop + Microsoft Teams)
- Faça o Commit: No GitHub Desktop, digite a mensagem (ex:
Finaliza Capítulo 18 Go_CargaExplosiva) e clique em Commit to main. - Envie para a Nuvem (Push): Clique em Push origin.
8. 📂 Estrutura de Pastas
spec_backend_com_golang_e_gin/
├── capitulos/
│ └── capitulo_18_carga_explosiva.md💡 Checkpoint de Lógica
Em servidores profissionais, para não deixar o disco rígido lotar, os programadores sempre limitam o tamanho máximo do arquivo que o usuário pode enviar. No Gin, você faz isso adicionando a linha r.MaxMultipartMemory = 8 << 20 (para limitar em )!
10. 🔥 Desafio de Fixação
Pesquise como verificar a extensão do arquivo (se ele termina em .jpg ou .pdf) em Go para impedir que o usuário envie arquivos perigosos para o seu servidor.
🔑 Gabarito de Código/Fórmulas
Gabarito da Prática 1:
file, err := c.FormFile("curriculo")Gabarito da Prática 2:- O JSON foi feito para transportar apenas textos puros. Arquivos como imagens e PDFs são dados binários complexos e pesados. Para enviá-los, precisamos usar o formato
multipart/form-data, que fatia o arquivo em pedaços e os envia de forma eficiente pela rede!