API em Go: REST, GraphQL e gRPC — qual escolher em 2025

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

Por que Go é a linguagem ideal para APIs?

\n\n

Quando se trata de criar APIs de alta carga, Go (Golang) ocupa com confiança um lugar no topo. Sua natureza compilada, suporte embutido para concorrência através de goroutines e sintaxe minimalista permitem escrever microsserviços rápidos e confiáveis. Mas qual protocolo escolher para seu próximo projeto: o clássico REST, o flexível GraphQL ou o ultrarrápido gRPC?

\n\n

Neste artigo, não vamos apenas listar as diferenças — vamos escrever código real em Go para cada abordagem, analisar benchmarks e dar critérios claros de escolha. Vamos lá!

\n\n

API REST em Go: o clássico comprovado

\n\n

REST (Representational State Transfer) continua sendo o padrão de facto para APIs públicas. Go oferece uma excelente biblioteca padrão net/http, além de frameworks populares como gin e echo.

\n\n

Exemplo de servidor REST em Go puro

\n\n

Vamos começar com um serviço CRUD simples para gerenciar tarefas. Veja como é uma API REST mínima em Go sem dependências externas:

\n\n
package main\n\nimport (\n    "encoding/json"\n    "log"\n    "net/http"\n    "sync"\n)\n\ntype Task struct {\n    ID   int    `json:"id"`\n    Name string `json:"name"`\n}\n\nvar (\n    tasks   = []Task{{ID: 1, Name: "Estudar Go"}}\n    mu      sync.Mutex\n    nextID  = 2\n)\n\nfunc getTasks(w http.ResponseWriter, r *http.Request) {\n    mu.Lock()\n    defer mu.Unlock()\n    w.Header().Set("Content-Type", "application/json")\n    json.NewEncoder(w).Encode(tasks)\n}\n\nfunc createTask(w http.ResponseWriter, r *http.Request) {\n    var task Task\n    if err := json.NewDecoder(r.Body).Decode(&task); err != nil {\n        http.Error(w, err.Error(), http.StatusBadRequest)\n        return\n    }\n    mu.Lock()\n    task.ID = nextID\n    nextID++\n    tasks = append(tasks, task)\n    mu.Unlock()\n    w.WriteHeader(http.StatusCreated)\n    json.NewEncoder(w).Encode(task)\n}\n\nfunc main() {\n    http.HandleFunc("/tasks", func(w http.ResponseWriter, r *http.Request) {\n        switch r.Method {\n        case http.MethodGet:\n            getTasks(w, r)\n        case http.MethodPost:\n            createTask(w, r)\n        default:\n            http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)\n        }\n    })\n    log.Println("API REST iniciada na porta :8080")\n    log.Fatal(http.ListenAndServe(":8080", nil))\n}\n
\n\n

Vantagens do REST em Go:

\n
    \n
  • Simplicidade e previsibilidade — cada endpoint retorna uma estrutura de dados fixa
  • \n
  • Excelente capacidade de cache através de cabeçalhos HTTP
  • \n
  • Amplo suporte de ferramentas (Swagger, Postman)
  • \n
\n\n

Desvantagens: Over-fetching e under-fetching de dados. Se o cliente precisa apenas do nome da tarefa, ele ainda receberá o JSON completo.

\n\n

GraphQL em Go: flexibilidade nas consultas

\n\n

GraphQL resolve o problema de redundância de dados. O cliente decide quais campos precisa. A comunidade Go oferece a poderosa biblioteca gqlgen, que gera código a partir do esquema.

\n\n

Exemplo de servidor GraphQL com gqlgen

\n\n

Primeiro, definimos o esquema schema.graphql:

\n\n
type Task {\n    id: ID!\n    name: String!\n}\n\ntype Query {\n    tasks: [Task!]!\n}\n\ntype Mutation {\n    createTask(name: String!): Task!\n}\n
\n\n

Agora, executamos a geração e escrevemos os resolvers em Go:

\n\n
package main\n\nimport (\n    "log"\n    "net/http"\n    "github.com/99designs/gqlgen/graphql/handler"\n    "github.com/99designs/gqlgen/graphql/playground"\n)\n\n// Supondo que o código gerado já exista\ntype Resolver struct {\n    tasks []Task\n    mu    sync.Mutex\n}\n\nfunc (r *Resolver) Tasks(ctx context.Context) ([]Task, error) {\n    r.mu.Lock()\n    defer r.mu.Unlock()\n    return r.tasks, nil\n}\n\nfunc (r *Resolver) CreateTask(ctx context.Context, name string) (*Task, error) {\n    r.mu.Lock()\n    defer r.mu.Unlock()\n                

Blogs

Book Recommendations