GraphQL API с Java: пошаговый туториал на практике

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

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

Начать курс

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

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

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

Статья будет полезна Java-разработчикам, которые хотят освоить современный подход к построению API и улучшить взаимодействие между клиентом и сервером.

1. Настройка проекта и зависимости

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

  • Spring Web — для запуска веб-сервера
  • Spring Boot DevTools — для ускорения разработки
  • Lombok — для сокращения шаблонного кода

После создания проекта добавьте в pom.xml основную библиотеку GraphQL:

<dependency>
    <groupId>com.graphql-java</groupId>
    <artifactId>graphql-java-spring-boot-starter-webmvc</artifactId>
    <version>2021-06-30T00-00-00-1e4b5e5</version>
</dependency>

Также понадобится библиотека для работы с инструментом GraphiQL (веб-интерфейс для тестирования запросов):

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

После добавления зависимостей обновите проект и запустите его. По умолчанию GraphiQL будет доступен по адресу http://localhost:8080/graphiql.

2. Создание модели данных и схемы GraphQL

Для демонстрации создадим простую модель Book (книга). Определим класс с полями id, title, author и pages.

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 int pages;
}

Теперь необходимо определить схему GraphQL. Создайте файл schema.graphqls в папке src/main/resources:

type Query {
    allBooks: [Book]
    bookById(id: String): Book
}

type Book {
    id: String
    title: String
    author: String
    pages: Int
}

Схема описывает два запроса: получение всех книг и получение книги по идентификатору. Тип Book содержит четыре поля.

Для обработки запросов создадим сервис, который будет хранить данные в памяти (для простоты):

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

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

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

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

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

3. Реализация резолверов (GraphQL Resolvers)

Резолверы — это классы, которые связывают запросы из схемы с реальными данными. В библиотеке graphql-java-spring-boot-starter-webmvc используется аннотация @QueryMapping.

Создадим класс BookResolver:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;

@Controller
public class BookResolver {

    @Autowired
    private BookService bookService;

    @QueryMapping
    public List<Book> allBooks() {
        return bookService.getAllBooks();
    }

    @QueryMapping
    public Book bookById(@Argument String id) {
        return bookService.getBookById(id);
    }
}

Обратите внимание на аннотацию @Argument — она позволяет передавать параметры из запроса GraphQL в метод.

Теперь, если запустить приложение и открыть GraphiQL, можно выполнить следующий запрос:

query {
  allBooks {
    id
    title
    author
  }
}

Ответ вернет только запрошенные поля. Например:

{
  "data": {
    "allBooks": [
      { "id": "1", "title": "Война и мир", "author": "Лев Толстой" },
      { "id": "2", "title": "Преступление и наказание", "author": "Фёдор Достоевский" },
      { "id": "3", "title": "Мастер и Маргарита", "author": "Михаил Булгаков" }
    ]
  }
}

Если нужно получить конкретную книгу, используйте запрос с аргументом:

query {
  bookById(id: "2") {
    title
    pages
  }
}

4. Добавление мутаций (Mutation) для изменения данных

GraphQL поддерживает не только чтение, но и изменение данных через мутации. Добавим возможность добавлять новую книгу.

Сначала расширим схему в файле schema.graphqls:

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

Затем добавим метод в сервис BookService:

public Book addBook(String title, String author, int pages) {
    String newId = String.valueOf(books.size() + 1);
    Book book                

Блоги

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