[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 здесь.

Понравился контент? Вы можете поддержать меня, купив мне кофе нажав здесь или по ссылке ниже.