Привет, Хабр!
Меня зовут Дмитрий, и я бэкенд-разработчик в SENSE с 10-летним опытом. За это время я успел поработать с финтех-проектами, автоматизировал обработку заказов для интернет-магазинов, но GraphQL долгое время оставался для меня загадочной технологией — я просто не сталкивался с ним в работе. А когда он мне понадобился, то обнаружил, что толковых материалов по Spring-реализации GraphQL очень мало. Поэтому, я решил не только разобраться самостоятельно в теме, но и написать гайд для тех, кто, как и я, только начинает погружаться в эту тему.
Разбираться будем постепенно: в первой статье покажу, как создать проект с GraphQL с нуля. Поехали!

Создание проекта
Создайте Spring Boot проект не ниже версии 3.5.3 (Java 21 + Maven) со следующими зависимостями:
Spring for GraphQL
Lombok
Spring Web

Проверьте в файле pom.xml
наличие 2-х главных зависимостей, которые понадобятся для примера:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql-test</artifactId>
<scope>test</scope>
</dependency>
Проверьте папку resources
на наличие:
папки
graphql
файла
application
(дальнейшие примеры содержат настройки в формате yml)

Чтобы работать через готовый UI с GraphQL включите его через application.yml:
spring:
graphql:
graphiql:
enabled: true
Создайте в папке graphql
файл query.graphqls.
Примечание: .graphqls и .gqls являются расширениями по умолчанию. Поменять их можно в конфиге spring.graphql.schema.file-extensions
В query.graphqls
(далее по тексту — “схема graphql”
) создайте query метод helloWorld:
type Query {
helloWorld: String
}
Положительным результат будет считаться тогда, когда при запуске приложения и при переходе по ссылке http://localhost:8080/graphiql, вам станет доступен UI интерфейс:


Отмечу, что UI graphiql использует внешние библиотеки. Но в некоторых регионах прямой доступ может быть ограничен, поэтому, стоит воспользоваться сервисом по обходу или postman.

Выполните запрос helloWorld
:

Поздравляю! Первичная настройка произведена ?
Создание простого @QueryMapping
На данном этапе запрос helloWorld
возвращает всегда null
, чтобы это изменить, необходимо создать контроллер для работы с запросом.
Спойлер: разработчики Spring
постарались сделать опыт работы со своим фреймворком понятным для тех, кто уже работал и реализовывал REST API
. Поэтому многое покажется знакомым.
Создайте контроллер для работы с запросом helloWorld
:
@Controller
public class HelloWorldController {
@QueryMapping
public String helloWorld() {
return "HI!";
}
}
Имя метода должно совпадать с именем запроса из схемы graphql по умолчанию или переопределено в аннотации @QueryMapping
.
Перезапустите приложение и повторно выполните запрос. Результат будет следующим:
{
"data": {
"helloWorld": "HI!"
}
}
Усложняем метод:
передаем String и выводим его в ответе;
делаем входящий и исходящий String обязательным посредством добавления «!» в схеме graphQL. Для этого меняем схему graphql и Controller.
type Query {
helloWorld(text: String!): String!
}
@QueryMapping
public String helloWorld(@Argument(name = "text") String msg) {
return msg;
}
Так как название параметров отличается, то в @Argument
добавили параметр name
. Если название будет одинаковым, то достаточно будет добавить @Argument
без параметра.
Создание простого @MutationMapping
В GraphQL запросы делятся на три типа:
mutation;
query;
subscription (его в данной статье рассматривать не будем).
Мутации (mutation) используются для изменения данных, в то время как запросы (query) используются для получения данных.
Хотя технически и возможно выполнить все операции через запросы, делать это не рекомендуется, поскольку может привести к путанице и усложнению кода. Настраивать схему можно в одном файле, но рекомендуется делить ее на несколько файлов для улучшения читаемости и организации кода.
Создайте новый файл mutation.graphqls
для определения мутаций в вашей схеме:
type Mutation {
mutationHelloWorld(text: String!): String!
}
Отредактируйте контроллер:
private String data = "Hello, World!";
@QueryMapping
public String helloWorld(@Argument String text) {
return text + " " + data;
}
@MutationMapping
public String mutationHelloWorld(@Argument String text) {
data = text;
return data;
}
Теперь mutation
изменяет значение data
, а query
возвращает свое значение + data
.
Тестирование @QueryMapping и @MutationMapping

@SpringBootTest
@AutoConfigureGraphQlTester
public class HelloWorldControllerTets {
@Autowired
protected GraphQlTester graphQlTester;
@Test
void queryTest() {
String query = """
query MyQuery {
helloWorld(text: "123")
}
""";
String response = graphQlTester.document(query).execute().path("helloWorld").entity(String.class).get();
assertThat(response).isEqualTo("123 Hello, World!");
}
@Test
void mutationTest() {
String query = """
mutation MyMutation {
mutationHelloWorld(text: "text")
}
""";
String response = graphQlTester.document(query).execute().path("mutationHelloWorld").entity(String.class).get();
assertThat(response).isEqualTo("text");
}
}
Ожидаемо, что если тест mutationTest
будет выполнен до queryTest, то queryTest провалится. Это связано с тем, что mutationTest
изменяет данные, которые затем используются в queryTest
.
В этой части гайда мы рассмотрели основы работы с Spring GraphQL: настройку проекта, создание схемы, реализацию запросов и мутаций, а также их тестирование.
В следующих частях мы углубимся в более сложные аспекты:
Работа с DataLoader для оптимизации запросов;
Расширенная валидация и обработка ошибок;
Интеграция с Spring Security и другими компонентами экосистемы Spring.
Spring GraphQL — это мощный инструмент, который сочетает гибкость GraphQL с удобством Spring, и в следующих статьях мы раскроем его потенциал еще больше.
А как вы уже испольовали GraphQL в своих проектах или только присматриваетесь? Буду рад обратной связи и готов ответить в комментариях на все оставшиеся вопросы!
KoIIIeY
Почему не котлин?
Richterdg92 Автор
Привет. Основная причина, что экспертизы больше на java :)