Примеры GraphQL на Java для начинающих [со Spring Boot]

от автора

В этой статье мы рассмотрим пример GraphQL на Java и создадим простой сервер GraphQL со Spring Boot.


Таким цыпочкам тоже нравятся примеры GraphQL на Java со Spring Boot!

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

В этой статье мы рассмотрим пример GraphQL на Java и создадим простой сервер GraphQL со Spring Boot.

Добавление зависимостей Maven

Создайте пример Spring Boot приложения и добавьте следующие зависимости.

  1. graphql-spring-boot-starter используется для включения сервлета GraphQL и будет доступен по пути /graphql. Он инициализирует GraphQLSchema бин.
  2. graphql-java позволяет нам писать схемы на языке схем GraphQL, который прост для понимания.
  3. graphiql-spring-boot-starter предоставляет пользовательский интерфейс, с помощью которого мы сможем тестировать наши запросы на GraphQL и просматривать определения запросов.
        <dependency>         <groupId>com.graphql-java</groupId>         <artifactId>graphql-spring-boot-starter</artifactId>         <version>5.0.2</version>     </dependency>     <dependency>         <groupId>com.graphql-java</groupId>         <artifactId>graphql-java-tools</artifactId>         <version>5.2.4</version>     </dependency>     <dependency>         <groupId>com.graphql-java</groupId>         <artifactId>graphiql-spring-boot-starter</artifactId>         <version>5.0.2</version>     </dependency>

    Вот полное содержимое файла POM.

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.techshard.graphql</groupId> <artifactId>springboot-graphql</artifactId> <version>1.0-SNAPSHOT</version> <parent>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-parent</artifactId>     <version>2.1.6.RELEASE</version>     <relativePath /> </parent> <properties>     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies>     <dependency>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-web</artifactId>     </dependency>     <dependency>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-data-jpa</artifactId>     </dependency>     <dependency>         <groupId>com.graphql-java</groupId>         <artifactId>graphql-spring-boot-starter</artifactId>         <version>5.0.2</version>     </dependency>     <dependency>         <groupId>com.graphql-java</groupId>         <artifactId>graphql-java-tools</artifactId>         <version>5.2.4</version>     </dependency>     <dependency>         <groupId>com.graphql-java</groupId>         <artifactId>graphiql-spring-boot-starter</artifactId>         <version>5.0.2</version>     </dependency>     <dependency>         <groupId>com.h2database</groupId>         <artifactId>h2</artifactId>         <scope>runtime</scope>     </dependency>     <dependency>         <groupId>org.projectlombok</groupId>         <artifactId>lombok</artifactId>         <version>1.18.8</version>         <optional>true</optional>     </dependency> </dependencies> <build>     <plugins>         <plugin>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-maven-plugin</artifactId>         </plugin>     </plugins> </build> </project>

    Создание сущности и репозитория JPA

    Давайте создадим простую сущность с именем Vehicle и соответствующий JPA репозиторий. Мы будем использовать Lombok, чтобы избежать написания шаблоного кода, такого как геттеры, сеттеры и так далее.

    package com.techshard.graphql.dao.entity; import lombok.Data; import lombok.EqualsAndHashCode; import javax.persistence.*; import java.io.Serializable; import java.time.LocalDate; @Data @EqualsAndHashCode @Entity public class Vehicle implements Serializable {     private static final long serialVersionUID = 1L;     @Id     @Column(name = "ID", nullable = false)     @GeneratedValue(strategy = GenerationType.AUTO)     private int id;     @Column(name = "type", nullable = false)     private String type;     @Column(name = "model_code", nullable = false)     private String modelCode;     @Column(name = "brand_name")     private String brandName;     @Column(name = "launch_date")     private LocalDate launchDate;     private transient  String formattedDate;     // Getter and setter     public String getFormattedDate() {         return getLaunchDate().toString();     } }

    Вот соответствующий репозиторий JPA.

    package com.techshard.graphql.dao.repository; import com.techshard.graphql.dao.entity.Vehicle; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface VehicleRepository extends JpaRepository<Vehicle, Integer> { }

    Схема GraphQL

    GraphQL поставляется с собственным языком для написания схем GraphQL, который называется Schema Definition Language (SDL — язык определения схемы). Определение схемы состоит из всех функций API, доступных в конечной точке.

    Типичный пример схемы GraphQL будет выглядеть так:

    type Vehicle { id: ID!, type: String, modelCode: String, brandName: String, launchDate: String } type Query { vehicles(count: Int):[Vehicle] vehicle(id: ID):Vehicle } type Mutation { createVehicle(type: String!, modelCode: String!, brandName: String, launchDate: String):Vehicle }

    Создайте папку graphql в папке src/main/resources и в ней создайте файл vehicleql.graphqls. Скопируйте вышеуказанное содержимое и вставьте его в файл vehicleql.graphqls. Обратите внимание, что именем файла может быть любое имя по вашему выбору. Просто убедитесь, что у имени файла есть расширение .graphqls.

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

    В нашей схеме есть объект с именем Vehicle, который является нашим объектом домена. Тип Query представляет запрос, который можно сделать на сервер GraphQL для извлечения данных. Этот запрос является интерактивным, данные можно изменить, и новые результаты можно увидеть. Структура запроса и результат одинаковы. Это важно в мире GraphQL, потому что мы всегда получаем ожидаемый результат.

    Ниже в этой статье мы увидим рабочий пример.

    Тип Mutation представляет запросы, которые используются для выполнения операций записи данных.

    Root Query

    Объекты Query или Mutation являются основными объектами GraphQL. У них нет связанных классов данных. В таких случаях классы распознавателя (resolver) будут реализовывать GraphQLQueryResolver или GraphQLMutationResolver. Эти распознаватели будут искать методы, которые соответствуют полями в соответствующих основных типах.

    Давайте определим основные распознаватели для Vehicle.

    package com.techshard.graphql.query; import com.coxautodev.graphql.tools.GraphQLQueryResolver; import com.techshard.graphql.dao.entity.Vehicle; import com.techshard.graphql.service.VehicleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; import java.util.Optional; @Component public class VehicleQuery implements GraphQLQueryResolver {     @Autowired     private VehicleService vehicleService;     public List<Vehicle> getVehicles(final int count) {         return this.vehicleService.getAllVehicles(count);     }     public Optional<Vehicle> getVehicle(final int id) {         return this.vehicleService.getVehicle(id);     } }

    В этом классе реализованы методы для получения одного объекта Vehicle и списка объектов Vehicle. Обратите внимание, что мы определили эти методы в нашей схеме выше.

    Теперь давайте определим распознаватель мутаций.

    package com.techshard.graphql.mutation; import com.coxautodev.graphql.tools.GraphQLMutationResolver; import com.techshard.graphql.dao.entity.Vehicle; import com.techshard.graphql.service.VehicleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.time.LocalDate; @Component public class VehicleMutation implements GraphQLMutationResolver {     @Autowired     private VehicleService vehicleService;     public Vehicle createVehicle(final String type, final String modelCode, final String brandName, final String launchDate) {         return this.vehicleService.createVehicle(type, modelCode, brandName, launchDate);     } }

    В этом классе у нас есть только один метод для создания объекта Vehicle, и это соответствует типу Mutation в нашем определении схемы.

    Теперь мы определим сервис, который будет выполнять реальные транзакции.

    package com.techshard.graphql.service; import com.techshard.graphql.dao.entity.Vehicle; import com.techshard.graphql.dao.repository.VehicleRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @Service public class VehicleService {     private final VehicleRepository vehicleRepository ;     public VehicleService(final VehicleRepository vehicleRepository) {         this.vehicleRepository = vehicleRepository ;     }     @Transactional     public Vehicle createVehicle(final String type,final String modelCode, final String brandName, final String launchDate) {         final Vehicle vehicle = new Vehicle();         vehicle.setType(type);         vehicle.setModelCode(modelCode);         vehicle.setBrandName(brandName);         vehicle.setLaunchDate(LocalDate.parse(launchDate));         return this.vehicleRepository.save(vehicle);     }     @Transactional(readOnly = true)     public List<Vehicle> getAllVehicles(final int count) {         return this.vehicleRepository.findAll().stream().limit(count).collect(Collectors.toList());     }     @Transactional(readOnly = true)     public Optional<Vehicle> getVehicle(final int id) {         return this.vehicleRepository.findById(id);     } }

    Тестирование приложения

    Приложение теперь готово к тестированию. Запустите приложение Spring Boot и откройте в браузере эту ссылку: http://localhost:8080/graphiql. Мы увидим хороший пользовательский интерфейс, как показано ниже.

    В правой части пользовательского интерфейса мы можем изучить документацию.

    Теперь запустите следующий запрос.

    mutation {   createVehicle(type: "car", modelCode: "XYZ0192", brandName: "XYZ", launchDate: "2016-08-16")    {     id   } }

    Это создаст строку в таблице Vehicle. Результат должен быть:

    {   "data": {     "createVehicle": {       "id": "1"     }   } }

    Давайте теперь запустим запрос, чтобы получить данные.

    query {   vehicles(count: 1)    {     id,      type,      modelCode } }

    Вывод будет выглядеть так:

    {   "data": {     "vehicles": [       {         "id": "1",         "type": "bus",         "modelCode": "XYZ123"       }     ]   } }

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

    Вывод

    В этой статье мы рассмотрели базовый пример GraphQL на Java со Spring Boot. Ознакомьтесь с подробной документацией здесь.

    Полный исходный код этого руководства можно найти на GitHub.

    Дальнейшее чтение

    Introduction to GraphQL

    GraphQL: Core Features, Architecture, Pros, and Cons

    Если вам понравилась эта статья и вы хотите больше узнать о GraphQL, ознакомьтесь с этой коллекцией учебников и статей по всем вопросам, связанным с GraphQL.

    Прим. Переводчика.
    На русском языке также есть «Руководство по GraphQL для начинающих»

ссылка на оригинал статьи https://habr.com/ru/post/513170/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *