GraphQL API с Java: пошаговый туториал для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в GraphQL и Java

GraphQL — это современный язык запросов для API, разработанный Facebook. В отличие от REST, где каждый эндпоинт возвращает фиксированную структуру данных, GraphQL позволяет клиенту запрашивать именно те поля, которые ему нужны. Это снижает объем передаваемых данных и упрощает разработку сложных интерфейсов.

В этом туториале мы создадим простой GraphQL API на Java с использованием Spring Boot и библиотеки graphql-java. Вы узнаете, как настроить проект, определить схему, реализовать резолверы и протестировать API. Статья ориентирована на начинающих, поэтому мы будем двигаться шаг за шагом.

Для работы вам понадобятся: JDK 11+, Maven или Gradle, IDE (IntelliJ IDEA, Eclipse) и базовые знания Java.

1. Настройка проекта Spring Boot

Начнем с создания нового проекта Spring Boot. Самый простой способ — использовать Spring Initializr. Выберите следующие зависимости:

  • Spring Web
  • Spring Boot DevTools
  • Lombok (опционально, для упрощения кода)

После генерации проекта добавьте в pom.xml (или build.gradle) зависимость для GraphQL:

<dependency>
    <groupId>com.graphql-java</groupId>
    <artifactId>graphql-spring-boot-starter</artifactId>
    <version>5.0.2</version>
</dependency>
<dependency>
    <groupId>com.graphql-java</groupId>
    <artifactId>graphql-java-tools</artifactId>
    <version>5.2.4</version>
</dependency>

Эти библиотеки упростят интеграцию GraphQL с Spring Boot. После обновления зависимостей запустите проект командой mvn spring-boot:run или через IDE.

2. Определение схемы GraphQL

Схема — это основа GraphQL API. Она описывает типы данных, запросы (queries) и мутации (mutations). Создайте файл schema.graphqls в папке src/main/resources:

type Book {
    id: ID!
    title: String!
    author: String!
    year: Int
}

type Query {
    books: [Book]
    bookById(id: ID!): Book
}

type Mutation {
    addBook(title: String!, author: String!, year: Int): Book
}

Здесь мы определили тип Book с обязательными полями id, title, author и необязательным year. Query содержит два запроса: получение всех книг и книги по ID. Mutation позволяет добавлять новые книги.

Обратите внимание на восклицательный знак — он обозначает обязательное поле (non-null).

3. Реализация резолверов

Резолверы (resolvers) — это Java-классы, которые связывают схему с данными. Создадим класс Book как модель данных:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
    private String id;
    private String title;
    private String author;
    private Integer year;
}

Теперь создадим сервис для хранения книг (в реальном проекте здесь будет подключение к БД):

import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

@Service
public class BookService {
    private List<Book> books = new ArrayList<>();

    @PostConstruct
    public void init() {
        books.add(new Book("1", "Война и мир", "Лев Толстой", 1869));
        books.add(new Book("2", "Преступление и наказание", "Фёдор Достоевский", 1866));
    }

    public List<Book> getAllBooks() {
        return books;
    }

    public Optional<Book> getBookById(String id) {
        return books.stream().filter(b -> b.getId().equals(id)).findFirst();
    }

    public Book addBook(String title, String author, Integer year) {
        String id = UUID.randomUUID().toString();
        Book book = new Book(id, title, author, year);
        books.add(book);
        return book;
    }
}

И, наконец, резолверы для запросов и мутаций:

import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;

@Component
public class QueryResolver implements GraphQLQueryResolver {

    @Autowired
    private BookService bookService;

    public List<Book> getBooks() {
        return bookService.getAllBooks();
    }

    public Book getBookById(String id) {
        return bookService.getBookById(id).orElse(null);
    }
}

import com.coxautodev.graphql.tools.GraphQLMutationResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MutationResolver implements GraphQLMutationResolver {

    @Autowired
    private BookService bookService;

    public Book addBook(String title, String author, Integer year) {
        return bookService.addBook(title, author, year);
    }
}

Обратите внимание: имена методов в резолверах должны совпадать с именами полей в схеме (например, getBooks соответствует books).

4. Тестирование API с помощью GraphiQL

GraphiQL — это встроенная IDE для тестирования GraphQL запросов. Добавьте зависимость в pom.xml:

<dependency>
    <groupId>com.graphql-java</groupId>
    <artifactId>graphiql-spring-boot-starter</artifactId>
    <version>5.0.2</version>
</dependency>

Теперь запустите приложение и откройте браузер по адресу http://localhost:8080/graphiql. Вы увидите интерфейс для отправки запросов. Попробуйте выполнить:

query {
  books {
    id
    title
    author
    year
  }
}

Ответ должен содержать список книг. Теперь протестируем мутацию:

mutation {
  addBook(title: "Мастер и Маргарита", author: "Михаил Булгаков", year: 1967) {
    id
    title
    author
  }
}

После выполнения мутации вы увидите новую книгу в ответе. Можно также запросить книгу по ID:

query {
  bookById(id: "1") {
    title
    author
  }
}

GraphQL позволяет комбинировать запросы

Блоги

Рекомендаций по книгам