GraphQL API com Go: tutorial prático passo a passo

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 GraphQL e Go são a combinação perfeita

\n

No desenvolvimento web moderno, o GraphQL se tornou um padrão para criar APIs flexíveis e eficientes. Combinado com a linguagem Go (Golang), conhecida por seu desempenho e simplicidade, você obtém uma ferramenta poderosa para o desenvolvimento backend. Neste tutorial passo a passo, criaremos uma API GraphQL completa em Go do zero, usando a biblioteca popular gqlgen.

\n

Você aprenderá como configurar o projeto, definir o esquema, implementar resolvers e adicionar middleware para autenticação. Ao final do artigo, você terá uma API funcional, pronta para integração com qualquer frontend.

\n\n

1. Configuração do projeto e instalação de dependências

\n

Primeiro, criaremos um novo módulo Go e instalaremos os pacotes necessários. Certifique-se de ter o Go versão 1.18 ou superior instalado.

\n
mkdir graphql-go-tutorial\ncd graphql-go-tutorial\ngo mod init graphql-go-tutorial\ngo get github.com/99designs/gqlgen@latest\ngo get github.com/99designs/gqlgen/graphql/introspection@latest
\n

Agora, inicializaremos o gqlgen no projeto. Este comando criará a estrutura básica de arquivos:

\n
go run github.com/99designs/gqlgen init
\n

Após a execução, você verá a seguinte estrutura:

\n
    \n
  • graph/ — diretório com arquivos de esquema e resolvers
  • \n
  • graph/schema.graphqls — definição do esquema GraphQL
  • \n
  • graph/resolver.go — stubs para os resolvers
  • \n
  • server.go — ponto de entrada da aplicação
  • \n
  • gqlgen.yml — configuração do gerador
  • \n
\n\n

2. Definição do esquema GraphQL

\n

Abriremos o arquivo graph/schema.graphqls e definiremos nosso modelo de dados. Como exemplo, criaremos um sistema simples de gerenciamento de tarefas (Task Manager):

\n
type Task {\n  id: ID!\n  title: String!\n  description: String\n  status: TaskStatus!\n  createdAt: Time!\n}\n\nenum TaskStatus {\n  TODO\n  IN_PROGRESS\n  DONE\n}\n\ntype Query {\n  tasks(status: TaskStatus): [Task!]!\n  task(id: ID!): Task\n}\n\ntype Mutation {\n  createTask(title: String!, description: String): Task!\n  updateTask(id: ID!, title: String, description: String, status: TaskStatus): Task!\n  deleteTask(id: ID!): Boolean!\n}\n\nscalar Time
\n

Após salvar o esquema, executaremos a geração de código:

\n
go run github.com/99designs/gqlgen generate
\n

Este comando criará o arquivo graph/model/models_gen.go com as estruturas Go e atualizará os resolvers.

\n\n

3. Implementação dos resolvers e lógica de negócio

\n

Agora, implementaremos a lógica no arquivo graph/schema.resolvers.go. Primeiro, criaremos um armazenamento simples em memória (in-memory store):

\n
// Em graph/resolver.go adicionaremos o armazenamento\ntype Resolver struct {\n  tasks []*model.Task\n  mu    sync.Mutex\n}\n\nfunc NewResolver() *Resolver {\n  return &Resolver{\n    tasks: make([]*model.Task, 0),\n  }\n}
\n

Agora, implementaremos os resolvers para Query e Mutation:

\n
// Query.Task\nfunc (r *queryResolver) Task(ctx context.Context, id string) (*model.Task, error) {\n  r.mu.Lock()\n  defer r.mu.Unlock()\n  \n  for _, task := range r.tasks {\n    if task.ID == id {\n      return task, nil\n    }\n  }\n  return nil, fmt.Errorf("task not found")\n}\n\n// Mutation.CreateTask\nfunc (r *mutationResolver) CreateTask(ctx context.Context, title string, description *string) (*model.Task, error) {\n  r.mu.Lock()\n  defer r.mu.Unlock()\n  \n  task := &model.Task{\n    ID:          uuid.New().String(),\n    Title:       title,\n    Description: description,\n    Status:      model.TaskStatusTodo,\n    CreatedAt:   time.Now(),\n  }\n  \n  r.tasks = append(r.tasks, task)\n  return task, nil\n}\n\n// Mutation.UpdateTask\nfunc (r *mutationResolver) UpdateTask(ctx context.Context, id string, title *string, description *string, status *model.TaskStatus) (*model.Task, error) {\n  r.mu.Lock()\n  defer r.mu.Unlock()\n  \n  for _, task                

Blogs

Book Recommendations