GraphQL библиотека Go (Golang) — мощный инструмент для создания API
GraphQL — это язык запросов для API, который позволяет клиентам запрашивать только те данные, которые им действительно нужны. В экосистеме Go (Golang) одной из самых популярных библиотек для работы с GraphQL является gqlgen (GraphQL Go Generate). Эта библиотека позволяет создавать типобезопасные серверы GraphQL с минимальным количеством шаблонного кода. В этой статье мы подробно разберем gqlgen, его установку, настройку и примеры использования.
Что такое gqlgen?
gqlgen — это генератор кода для Go, который автоматически создает резолверы и типы на основе вашей GraphQL схемы. Основные преимущества:
- Типобезопасность — все типы проверяются на этапе компиляции
- Минимум шаблонного кода — библиотека генерирует большую часть кода за вас
- Гибкость — поддержка подписок, мутаций и сложных запросов
- Производительность — высокая скорость работы, характерная для Go
Установка gqlgen
Для начала работы установите библиотеку и утилиту командной строки:
go get github.com/99designs/gqlgen
go run github.com/99designs/gqlgen init
Команда init создаст базовую структуру проекта с файлами schema.graphqls, gqlgen.yml и сгенерированным кодом.
Структура проекта
После инициализации вы получите следующую структуру:
my-graphql-app/
├── gqlgen.yml # Конфигурация генератора
├── graph/
│ ├── schema.graphqls # GraphQL схема
│ ├── resolver.go # Резолверы (ваш код)
│ └── models_gen.go # Сгенерированные модели (не редактировать)
├── server.go # Точка входа
└── go.mod
Написание GraphQL схемы
Пример файла schema.graphqls для простого блога:
type Query {
posts: [Post!]!
post(id: ID!): Post
}
type Mutation {
createPost(input: PostInput!): Post!
deletePost(id: ID!): Boolean!
}
type Post {
id: ID!
title: String!
content: String!
author: String!
createdAt: Time!
}
input PostInput {
title: String!
content: String!
author: String!
}
scalar Time
Генерация кода
После описания схемы выполните:
go run github.com/99designs/gqlgen generate
Это создаст файлы models_gen.go и generated.go с типами и интерфейсами резолверов.
Реализация резолверов
Теперь нужно реализовать логику в resolver.go:
package graph
import (
"context"
"time"
)
// Модель данных
type Post struct {
ID string `json:"id"`
Title string `json:"title"`
Content string `json:"content"`
Author string `json:"author"`
CreatedAt time.Time `json:"createdAt"`
}
// Хранилище в памяти
var posts = []*Post{
{
ID: "1",
Title: "Введение в GraphQL",
Content: "GraphQL — это язык запросов...",
Author: "Иван Петров",
CreatedAt: time.Now(),
},
}
// Резолвер для Query.posts
func (r *queryResolver) Posts(ctx context.Context) ([]*Post, error) {
return posts, nil
}
// Резолвер для Query.post
func (r *queryResolver) Post(ctx context.Context, id string) (*Post, error) {
for _, post := range posts {
if post.ID == id {
return post, nil
}
}
return nil, nil
}
// Резолвер для Mutation.createPost
func (r *mutationResolver) CreatePost(ctx context.Context, input PostInput) (*Post, error) {
newPost := &Post{
ID: fmt.Sprintf("%d", len(posts)+1),
Title: input.Title,
Content: input.Content,
Author: input.Author,
CreatedAt: time.Now(),
}
posts = append(posts, newPost)
return newPost, nil
}
Запуск сервера
Файл server.go уже содержит базовый код для запуска HTTP сервера. Дополните его:
package main
import (
"log"
"net/http"
"os"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/playground"
"your-project/graph"
)
func main() {
// Создаем экземпляр сервера
srv := handler.New