Biblioteca gqlgen para Go (Golang): Criando uma API GraphQL
GraphQL tornou-se o padrão de facto para a construção de APIs modernas devido à sua flexibilidade e eficiência. No ecossistema Go (Golang), uma das bibliotecas mais poderosas e populares para trabalhar com GraphQL é a gqlgen. Ela oferece aos desenvolvedores uma maneira conveniente de definir esquemas, geração automática de código padrão e alto desempenho.
O que é gqlgen e por que escolhê-la?
gqlgen (abreviação de "graphql generator") é uma biblioteca para Go que constrói um servidor GraphQL com base no esquema. Sua principal característica é a abordagem code-first: você descreve o esquema em um arquivo .graphql, e a biblioteca gera todo o código Go necessário (structs, interfaces para resolvers). Isso elimina a escrita repetitiva de código boilerplate e reduz a probabilidade de erros.
Principais vantagens:
- Geração automática de código: tipos, métodos e interfaces de resolvers são criados a partir do esquema.
- Segurança de tipos: todos os tipos são verificados em tempo de compilação do Go.
- Desempenho: a biblioteca é otimizada para funcionar em sistemas de alta carga.
- Suporte a Subscriptions: possibilidade de implementar funcionalidades em tempo real via WebSocket.
- Flexibilidade: integra-se facilmente com bancos de dados, caches e outros serviços.
Instalação e configuração
Para começar, é necessário instalar o gqlgen e inicializar o projeto:
// Instalação da bibliotecago get github.com/99designs/gqlgen@latest
// Inicialização do esqueleto do projetogo run github.com/99designs/gqlgen initApós executar o comando init, a estrutura do projeto será criada:
graph/schema.graphqls— arquivo com o esquema.graph/resolver.go— resolver raiz.graph/schema.resolvers.go— stubs gerados para os resolvers.server.go— ponto de entrada para iniciar o servidor.
Definição do esquema GraphQL
No arquivo schema.graphqls, são descritos os tipos, consultas e mutações. Exemplo de esquema para um sistema de blog:
# Definição do tipo Usertype User { id: ID! name: String! email: String! posts: [Post!]!}
# Definição do tipo Posttype Post { id: ID! title: String! content: String! author: User!}
# Tipo raiz Querytype Query { user(id: ID!): User users: [User!]! post(id: ID!): Post posts: [Post!]!}
# Tipo raiz Mutationtype Mutation { createUser(name: String!, email: String!): User! createPost(title: String!, content: String!, authorId: ID!): Post!}Geração de código e implementação de resolvers
Após descrever o esquema, execute a geração de código:
go run github.com/99designs/gqlgen generateA biblioteca criará arquivos com structs e interfaces Go. Agora é necessário implementar os resolvers — funções que retornam os dados. Exemplo de implementação de um resolver para obter um usuário:
// graph/schema.resolvers.go (exemplo de implementação)func (r *queryResolver) User(ctx context.Context, id string) (*model.User, error) { // Lógica para obter o usuário do banco de dados user, err := r.db.GetUserByID(ctx, id) if err != nil { return nil, err } return user, nil}
func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) { // Lógica para obter a lista de todos os usuários return r.db.GetAllUsers(ctx)}
// Resolver para o campo posts em User (resolução de dados aninhados)func (r *userResolver) Posts(ctx context.Context, obj *model.User) ([]*model.Post, error) { // obj é o objeto User para o qual os posts estão sendo solicitados