Привет, Хабр!
Меня зовут Дмитрий, и я бэкенд-разработчик в 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 в своих проектах или только присматриваетесь? Буду рад обратной связи и готов ответить в комментариях на все оставшиеся вопросы!
ссылка на оригинал статьи https://habr.com/ru/articles/932054/
Добавить комментарий