[GraphQL] с примером запроса, мутации и подписки на основе Java Spring Boot Annotation

Что такое GraphQL?
GraphQL — это язык запросов для API и среда выполнения сервера для обработки этих запросов. Он в основном используется для запроса только тех данных, которые вам нужны, что сокращает время отклика и снижает использование пропускной способности сети. , что ограничивает количество необходимых вам запросов.
GraphQL был создан в 2012 году компанией Facebook и стал открытым в 2015 году. Он решает важную проблему получения только необходимых данных из одного места, а не делает запросы к нескольким микросервисам и получает в ответ тонны нежелательных данных. Это очень полезно для сетей и сред с ограниченной производительностью, таких как мобильные устройства.
В этой статье мы изучим базовую терминологию и создадим пример приложения с использованием Java, Spring Boot и GraphQL. Ссылка на GitHub будет опубликована в конце статьи.
Терминология GraphQL
GraphQL имеет клиент-серверную архитектуру для обмена данными. Клиент отправляет запросы на сервер для выполнения различных действий, таких как выборка данных или создание/обновление/удаление данных.
GraphQL: Схема
Схема описывает все возможные данные, которые клиенты могут запрашивать через службу. Он состоит из типов объектов. Нажмите здесь, чтобы перейти на страницу официальной документации.
GraphQL: язык ввода
Сервисы GraphQL могут быть написаны на любом языке. Он использует «язык схем GraphQL», он похож на язык запросов и позволяет нам говорить о схемах GraphQL независимо от языка.
GraphQL: типы объектов и поля
Самый простой/используемый компонент в GraphQL относится к типу объекта type. Он также имеет типы масштабирования, такие как 'Int', 'String', 'Float', 'Boolean', и "ID".
Например, ниже показан тип объекта в схеме GraphQL. Обратите внимание, что ‘!’ используется для обозначения ненулевых значений, вы всегда получите обратно значение для этого поля.
type Address {
addressId: ID!,
houseNumber: Int,
street: String,
city: String,
zipcode: String,
country: String
}
GraphQL: запрос, мутация и подписка
GraphQL имеет 3 типа операций, которые мы можем использовать для чтения и записи данных.
Запрос: используется для чтения данных.
Мутация: используется для записи данных (создание/обновление/удаление)
Подписка : Аналогичен Query, но здесь соединение длится дольше, и сервер может отправлять данные в любое время, не запрашивая их на основе какой-либо подписки.
Вариант использования для этой истории
Мы создадим простую схему GraphQL с Пользователь и Адрес в качестве типа объекта. Мы создадим Запрос для получения данных о Пользователе, Мутацию для создания нового Пользователя и Подписку для приветствия только что созданного Пользователя.
Необходимое условие
- Джава
- Весенняя загрузка (2.7+)
- Грейдл или Мейвен
Настраивать
Давайте создадим новый проект Spring Boot с помощью Spring Initializer с именем graphql-spring-example, обновим сведения о проекте, добавим GraphQL, Web, и WebSocket в зависимостях и нажмите Создать. Или просто нажмите здесь, чтобы загрузить проект напрямую.
Я буду использовать Java 17 с IntelliJ IDEA IDE. Вы можете использовать свою любимую конфигурацию.
Файл схемы GraphQL
Давайте теперь создадим каталог с именем «graphql» в каталоге «src/main/resources» и добавим туда файл схемы. Расширение файла схемы должно быть «.graphqls».
Реализация Java-сервера GraphQL
Теперь, когда мы создали нашу схему, пришло время создать реализацию на стороне сервера.
Мы создадим класс Controller с аннотацией «@Controller». Затем мы создадим 4 метода: 2 для запросов, 1 для мутации и 1 для подписки. Мы снабдим их аннотациями «@QueryMapping», «@MutationMapping» и «@SubscriptionMapping» в соответствии со схемой.
Это будет выглядеть примерно так:
@Controller
public class GraphqlController {
@QueryMapping
public Collection<User> getAllUsers() {
return null;
}
@QueryMapping
public User getUserById(@Argument int userId) {
return null;
}
@MutationMapping
public User addNewUser(@Argument UserInput user) {
return null;
}
@SubscriptionMapping
public Publisher<String> greetNewUsers() {
return null;
}
}
‘@Argument’ используется здесь для получения ввода.
Мы создадим класс службы с именем «GraphqlService» и добавим логику в этот класс. Для простоты мы будем использовать здесь данные в памяти. Это будет выглядеть примерно так:
Пожалуйста, обратите внимание, что я автоматически подключил приемник и поток, он используется для работы по подписке. Когда добавляется новый пользователь, он добавит данные в «userSink», и мы настроим его таким образом, чтобы он передавал данные в «userFlux», что отправить данные подписчику. Мы использовали Sink для простоты, мы также можем использовать любую систему обмена сообщениями, такую как JMS, Kafka и т. д. Файл конфигурации будет выглядеть примерно так:
Мы также создадим метод с аннотацией «@BatchMapping» в нашем контроллере для получения адреса. Это поможет получить адрес, когда мы получим всех пользователей, а данные адреса нужны в ответе. Этот метод не будет вызываться, если мы не будем запрашивать адресные данные в пользовательском запросе, мы увидим пример ниже.
Теперь давайте обновим реализацию контроллера.
Мы добавили оператор печати в метод сопоставления «address», он будет печататься только тогда, когда в запросе запрашивается адрес.
Давайте включим пользовательский интерфейс 'graphiql' с помощью конфигурации 'application.properties', мы также включим WebSocket, чтобы сопоставление 'Subscription' могло работа.
spring.graphql.graphiql.enabled=true spring.graphql.websocket.path=/graphql
Теперь давайте запустим наше приложение и перейдем по URL-адресу http://localhost:8080/graphiql в браузере. Откроется веб-страница, на которой мы будем выполнять наши запросы, она должна выглядеть примерно так:

Клиентские запросы GraphQL
Запрос. Теперь давайте попробуем выполнить «Запрос». Введите следующее в текстовое поле слева и нажмите кнопку запуска:
query Q {
getAllUsers {
userId
firstName
lastName
}
}
Необязательное имя запроса здесь — «Q», вы можете переименовать его в соответствии с вашими потребностями или удалить его.
Мы видим, что в ответе нет никаких данных, потому что мы еще не создали ни одного пользователя.
Мутация. Теперь давайте создадим пользователя, выполнив следующую команду «Мутация» (когда вы начнете вводить текст в этом пользовательском интерфейсе, вы заметите, что он начнет предлагать детали схемы):
mutation M($user:UserInput) {
addNewUser (user: $user) {
userId
firstName
lastName
address {
addressId
street
city
zipcode
}
}
}
Здесь мы будем использовать тип «UserInput», определенный в схеме, для ввода данных. Кроме того, мы видим, что в этой мутации он передается как переменная '$user'.
В левом нижнем углу пользовательского интерфейса мы видим 'variable' для передачи переменной. Щелкнем там и добавим значение «user».
{
"user": {
"firstName": "Prabhash",
"lastName": "Kumar",
"houseNumber":159,
"street":"RandomStr.",
"city":"Berlin",
"zipcode":"10295",
"country":"DE"
}
}
Давайте выполним сейчас, нажав кнопку запуска посередине, как и раньше, это должно дать результат, подобный этому:

Мы видим, что он ответил только теми данными, которые мы запросили. Мы не запрашивали «Страна», и в ответе не указана страна.
Теперь, когда мы добавили пользователя, давайте снова выполним запрос ‘getAllUsers()’. Теперь он должен дать ответ с одним использованием без какого-либо адресного объекта в ответе.
Мы также можем заметить в журналах вывода консоли, что для этого запроса метод сопоставления «address» не вызывается. Он был вызван только для нашего запроса «Mutation», когда мы запросили адрес в ответе. Это одна из лучших функций GraphQL, она может помочь в сохранении сетевых вызовов, будь то база данных или API.
Подписка. Давайте теперь создадим 'Подписку' в соответствии с нашей реализацией, когда мы создадим нового пользователя с помощью мутации, этот подписчик должен иметь возможность чтобы получить приветственное сообщение от сервера, приветствующее нового пользователя.
Давайте теперь откроем другую вкладку браузера и нажмем тот же URL-адрес http://localhost:8080/graphiql, здесь мы будем использовать его для подписки на событие, а в нашем предыдущем окне мы создадим нового пользователя, используя тот же запрос Mutation.
Запрос на подписку будет выглядеть следующим образом:
subscription s {
greetNewUsers
}
Теперь выполните этот запрос, вернитесь в предыдущее окно и создайте нового пользователя с новым именем (я использовал имя «John Doe»), и вы должны увидеть, что подписчик получил приветственное сообщение. с сервера для нового пользователя. Это должно выглядеть примерно так:
{
"data": {
"greetNewUsers": "Hello John Doe!"
}
}
Давайте попробуем, создав несколько пользователей, и увидим, что для каждого пользователя мы получаем приветственное сообщение. Мы также можем увидеть всех пользователей, вызвав запрос ‘getAllUsers’.
Заключение
В этой статье мы узнали о GraphQL и его реализации с помощью Java и Spring Boot. Мы создали схему, запустили сервер и выполнили все три запроса, мутацию и подписку с примерами.
Вы можете найти код этого примера в этом репозитории GitHub здесь.
Понравился контент? Вы можете поддержать меня, купив мне кофе нажав здесь или по ссылке ниже.