🚀 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-data para 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".

  1. 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

  1. 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)

  1. Faça o Commit: No GitHub Desktop, digite a mensagem (ex: Finaliza Capítulo 18 Go_CargaExplosiva) e clique em Commit to main.
  2. 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:

  1. file, err := c.FormFile("curriculo") Gabarito da Prática 2:
  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!

Capitulo Anterior | Proximo Capitulo