Introdução: Por que GraphQL e Go são a Dupla Perfeita
O desenvolvimento web moderno exige APIs flexíveis e de alto desempenho. A API REST, apesar de sua popularidade, frequentemente sofre com o excesso ou a falta de dados. GraphQL resolve esse problema permitindo que o cliente solicite exatamente o que é necessário. E o Go (Golang), com sua velocidade, simplicidade e suporte nativo a concorrência, torna-se a linguagem ideal para construir servidores GraphQL.
Neste tutorial, vamos criar passo a passo uma API GraphQL completa em Go. Você aprenderá a configurar um servidor, definir um esquema, escrever resolvers e implementar consultas e mutações. Ao final do artigo, você terá uma API funcional pronta para integração com qualquer cliente.
Passo 1: Configuração do Projeto e Instalação de Dependências
Primeiro, vamos criar um novo módulo Go e instalar as bibliotecas necessárias. Usaremos duas bibliotecas GraphQL populares: graphql-go e graphql-go-handler.
1.1. Inicialização do Módulo
go mod init graphql-tutorial1.2. Instalação das Bibliotecas
go get github.com/graphql-go/graphqlgo get github.com/graphql-go/handlerEssas bibliotecas fornecem todas as ferramentas necessárias para trabalhar com esquemas, tipos e resolvers.
Passo 2: Criando um Esquema GraphQL Básico
O esquema é o coração de uma API GraphQL. Ele define quais dados podem ser recuperados e quais ações podem ser realizadas. Vamos começar com um modelo simples de "Usuário".
2.1. Definindo o Tipo Usuário
import "github.com/graphql-go/graphql"
var userType = graphql.NewObject(graphql.ObjectConfig{ Name: "User", Fields: graphql.Fields{ "id": &graphql.Field{ Type: graphql.Int, }, "name": &graphql.Field{ Type: graphql.String, }, "email": &graphql.Field{ Type: graphql.String, }, },})2.2. Criando a Consulta Raiz
var rootQuery = graphql.NewObject(graphql.ObjectConfig{ Name: "RootQuery", Fields: graphql.Fields{ "user": &graphql.Field{ Type: userType, Args: graphql.FieldConfigArgument{ "id": &graphql.ArgumentConfig{ Type: graphql.Int, }, }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { id, _ := p.Args["id"].(int) // Aqui estará a lógica para obter o usuário do BD return getUserByID(id), nil }, }, },})2.3. Combinando em um Esquema
var schema, _ = graphql.NewSchema(graphql.SchemaConfig{ Query: rootQuery,})Passo 3: Implementando Resolvers e o Servidor
Agora que o esquema está pronto, precisamos escrever os resolvers — funções que realmente retornam os dados. Para simplificar, usaremos um armazenamento em memória.
3.1. Armazenamento em Memória
type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"`}
var users = []User{ {ID: 1, Name: "Ivan Petrov", Email: "ivan@example.com"}, {ID: 2, Name: "Maria Sidorova", Email: "maria@example.com"},}
func getUserByID(id int) *User { for _, u := range users { if u.ID == id { return &u } } return nil}3.2. Iniciando o Servidor HTTP
package main
import ( "fmt" "log" "net/http"
"github.com/graphql-go/handler")
func main() { h := handler.New(&handler.Config{ Schema: &schema, Pretty: true, GraphiQL: true, // Habilitar IDE integrada })
http.Handle("/graphql", h) fmt.Println("Servidor iniciado em")