Como escrever uma API REST em Go em 30 minutos: guia prático

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que Go para API REST?

\n

Go (Golang) é uma linguagem compilada moderna com suporte embutido para concorrência e alto desempenho. Uma API REST em Go funciona rápido, consome pouca memória e é facilmente escalável. Em 30 minutos, você criará um serviço REST completo com requisições GET, POST, PUT e DELETE, usando apenas a biblioteca padrão.

\n

Neste guia, escreveremos uma API para gerenciar uma lista de tarefas (Todo app). Você aprenderá como configurar o roteamento, processar JSON, adicionar middleware para logging e retornar erros corretamente. Sem frameworks de terceiros — apenas Go puro!

\n\n

1. Configuração do projeto e estrutura

\n

Crie um novo diretório para o projeto e inicialize o módulo Go:

\n
mkdir go-todo-api\ncd go-todo-api\ngo mod init todo-api
\n

A estrutura do projeto será simples:

\n
    \n
  • main.go — ponto de entrada e inicialização do servidor
  • \n
  • handlers.go — manipuladores de requisições
  • \n
  • models.go — estruturas de dados
  • \n
  • middleware.go — middleware
  • \n
\n

Crie o arquivo models.go com a estrutura da tarefa:

\n
package main\n\ntype Task struct {\n    ID        int    `json:"id"`\n    Title     string `json:"title"`\n    Completed bool   `json:"completed"`\n}
\n

Armazenaremos as tarefas em memória (slice tasks) para simplificar. Em um projeto real, use um banco de dados.

\n\n

2. Roteamento e manipuladores

\n

Go usa o pacote embutido net/http. Vamos criar o arquivo handlers.go com os principais manipuladores.

\n

2.1. GET /tasks — obter todas as tarefas

\n
package main\n\nimport (\n    "encoding/json"\n    "net/http"\n    "strconv"\n)\n\nvar tasks = []Task{}\nvar nextID = 1\n\nfunc getTasks(w http.ResponseWriter, r *http.Request) {\n    w.Header().Set("Content-Type", "application/json")\n    json.NewEncoder(w).Encode(tasks)\n}
\n

2.2. POST /tasks — criar uma nova tarefa

\n
func createTask(w http.ResponseWriter, r *http.Request) {\n    var newTask Task\n    if err := json.NewDecoder(r.Body).Decode(&newTask); err != nil {\n        http.Error(w, "Invalid JSON", http.StatusBadRequest)\n        return\n    }\n    newTask.ID = nextID\n    nextID++\n    tasks = append(tasks, newTask)\n    w.Header().Set("Content-Type", "application/json")\n    w.WriteHeader(http.StatusCreated)\n    json.NewEncoder(w).Encode(newTask)\n}
\n

2.3. PUT /tasks/{id} — atualizar uma tarefa

\n
func updateTask(w http.ResponseWriter, r *http.Request) {\n    idStr := r.PathValue("id")\n    id, err := strconv.Atoi(idStr)\n    if err != nil {\n        http.Error(w, "Invalid task ID", http.StatusBadRequest)\n        return\n    }\n    \n    var updatedTask Task\n    if err := json.NewDecoder(r.Body).Decode(&updatedTask); err != nil {\n        http.Error(w, "Invalid JSON", http.StatusBadRequest)\n        return\n    }\n    \n    for i, t := range tasks {\n        if t.ID == id {\n            tasks[i].Title = updatedTask.Title\n            tasks[i].Completed = updatedTask.Completed\n            w.Header().Set("Content-Type", "application/json")\n            json.NewEncoder(w).Encode(tasks[i])\n            return\n        }\n    }\n    http.Error(w, "Task not found", http.StatusNotFound)\n}
\n

2.4. DELETE /tasks/{id} — excluir uma tarefa

\n
func deleteTask(w http.ResponseWriter, r *http.Request) {\n    idStr := r.PathValue("id")\n    id, err := strconv.Atoi(idStr)\n    if err != nil {\n        http.Error(w, "Invalid task ID", http.StatusBadRequest)\n        return\n    }\n    \n    for i, t := range tasks {\n        if t.ID == id {\n            tasks = append(tasks[:i], tasks[i+1:]...)\n            w.WriteHeader(http.StatusNoContent)\n            return\n        }\n    }\n    http.Error(w, "Task not found", http.StatusNotFound)\n}
\n

Observe

Blogs

Book Recommendations