Введение в GraphQL и Go
GraphQL — это язык запросов для API, который позволяет клиентам получать именно те данные, которые им нужны, и ничего лишнего. В отличие от REST, где каждый эндпоинт возвращает фиксированную структуру данных, GraphQL даёт гибкость и контроль. В сочетании с Go (Golang) — быстрым, типобезопасным и простым языком — вы получаете мощный инструмент для создания современных веб-сервисов.
В этом туториале мы создадим простой GraphQL API на Go с нуля. Вы научитесь устанавливать зависимости, описывать схему, реализовывать резолверы и запускать сервер. Статья ориентирована на начинающих, поэтому все шаги подробно объяснены.
1. Подготовка проекта и установка зависимостей
Прежде чем писать код, убедитесь, что у вас установлен Go версии 1.18 или выше. Создайте новую директорию для проекта и инициализируйте модуль:
mkdir graphql-go-tutorial
cd graphql-go-tutorial
go mod init graphql-go-tutorial
Выбор библиотеки: gqlgen
Существует несколько библиотек для работы с GraphQL в Go. Мы будем использовать gqlgen — популярный генератор кода, который создаёт типы и резолверы на основе схемы. Установите его:
go get github.com/99designs/gqlgen@latest
Инициализация gqlgen
Выполните команду для создания файлов по умолчанию:
go run github.com/99designs/gqlgen init
Эта команда создаст несколько файлов:
graph/schema.graphqls— файл схемы GraphQL;graph/resolver.go— заготовка резолверов;server.go— точка входа сервера;gqlgen.yml— конфигурация генерации.
2. Описание схемы GraphQL
Откройте файл graph/schema.graphqls. По умолчанию там уже есть пример с типом Todo. Мы расширим его, добавив тип User и несколько запросов.
Замените содержимое файла на следующее:
type User {
id: ID!
name: String!
email: String!
}
type Todo {
id: ID!
text: String!
done: Boolean!
user: User!
}
type Query {
todos: [Todo!]!
users: [User!]!
user(id: ID!): User
}
type Mutation {
createTodo(text: String!, userId: ID!): Todo!
markDone(id: ID!): Todo!
}
Здесь мы определили:
- User — пользователь с полями id, name, email.
- Todo — задача с полями id, text, done и ссылкой на пользователя.
- Query — точки входа для чтения данных.
- Mutation — операции для изменения данных.
3. Генерация кода и реализация резолверов
После описания схемы нужно сгенерировать Go-код. Выполните:
go run github.com/99designs/gqlgen generate
Это создаст файлы models_gen.go и обновит resolver.go. Теперь откройте graph/resolver.go.
Добавление хранилища данных
Для простоты будем хранить данные в памяти. Добавьте структуру в resolver.go:
type Resolver struct {
Users []*model.User
Todos []*model.Todo
}
Не забудьте импортировать пакет model.
Реализация запросов (Query)
Найдите сгенерированные методы для Query. Реализуем их:
func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) {
return r.Resolver.Todos, nil
}
func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) {
return r.Resolver.Users, nil
}
func (r *queryResolver) User(ctx context.Context, id string) (*model.User, error) {
for _, u := range r.Resolver.Users {
if u.ID == id {
return u, nil
}
}
return nil, fmt.Errorf("user not found")
}
Реализация мутаций (Mutation)
Теперь добавим мутации. Они находятся в файле graph/schema.resolvers.go:
func (r *mutationResolver) CreateTodo(ctx context.Context, text string, userID string) (*model.Todo, error) {
todo := &model.Todo{
ID: fmt.Sprintf("todo-%d", len(r.Resolver.Todos)+1),
Text: text,
Done: false,
User: &model.User{ID: userID},
}
r.Resolver.Todos = append(r.Resolver.Todos, todo)
return todo, nil
}
func (r *mutationResolver) MarkDone(ctx context.Context, id string) (*model.Todo, error) {
for _, t := range r.Resolver.Todos {
if t.ID == id {
t.Done = true
return t, nil
}
}
return nil, fmt.Errorf("todo not found")
}
4. Запуск и тестирование API
Откройте server.go. В функции main замените инициализацию резолвера:
srv := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{
Users: []*model.User{
{ID: "user-1", Name: "Alice", Email: "alice@example.com"},
{ID: "user-2", Name: "Bob", Email: "bob@example.com"},
},
}}))
Запустите сервер:
go run server.go
Сервер будет доступен по адресу http://localhost:8080. Откройте браузер и перейдите по этому адресу — вы увидите встроенную GraphQL IDE (Playground).
Примеры запросов
В Playground выполните следующие запросы:
Получение всех пользователей:
query {
users {
id
name
email
}
}
Создание задачи:
mutation {
createTodo(text: "Изучить GraphQL", userId: "user-1") {
id
text
done
}
}
Получение задач