Рубрики
Без рубрики

Первые впечатления от GraphQL на Java

GraphQL – это открытый язык запросов для гибкого представления данных. Он был разработан компанией Facebook… С тегами java, graphql.

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

Мы исследуем его использование для предоставления результатов обработки естественного языка для замены или дополнения REST .

Экосистема Java

GraphQL не зависит от языка программирования, и различные реализации существуют на многих языках для этого проекта мы используем Java и Spring Boot, поэтому естественным выбором является graphql-java . Возможно, это не единственная реализация java но он, безусловно, самый активный в это время. Этот основной проект остается верным спецификации, и существует ряд вспомогательных проектов для облегчения интеграции и использования.

Подход

В GraphQL вам необходимо объявить свою схему данных, чтобы клиенты могли анализировать систему и правильно запрашивать. Однако схема должна быть точным представлением ваших базовых классов данных. Хотя вы могли бы создать обе эти вещи вручную, создание одной из них из другой сократит усилия и ошибки. Один из подходов заключается в определении вашей схемы и создании классов данных. Этот подход обеспечивается graphql-apigen и graphql-java-инструментами . Хотя этот подход может быть очень полезен, если у вас есть новый проект со строгой спецификацией схемы, у нас уже есть классы данных. Поэтому мы используем подход, основанный на классах, и создаем схему. Существует проект graphql-java-аннотации , основанный на этом подходе, однако его разработка, похоже, остановилась, и сообщество, похоже, движется в направлении graphgql-spqr (произносится как “спикер”). Похоже, что это станет официальным подходом, основанным на классе graphql-java.

Приступая к работе

Было очень легко начать использовать graphql-spring-boot . Это дает:

  • Сервлет graphql-java для обслуживания схемы и приема запросов GET и POST GraphQL
  • Графический пользовательский интерфейс , для написания и выполнения запросов GraphQL к опубликованной схеме.
  • graphql-java-инструменты сначала схема
  • graphql spring общий первый класс

Мы решили не использовать последнее и добавили graphql-spqr просто, предоставив graphql.schema. Схема GraphQL Был сгенерирован с использованием graphql-spqr и аннотаций на Демонстрационном сервисе и используемых POJO.

package io.committed;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import graphql.schema.GraphQLSchema;
import io.committed.query.DemoService;
import io.leangen.graphql.GraphQLSchemaGenerator;

@Controller
@EnableAutoConfiguration
@ComponentScan
public class GrahpQLDemo {

  @Autowired
  DemoService demoService;

  @Bean
  GraphQLSchema schema() {
    return new GraphQLSchemaGenerator()
        .withOperationsFromSingleton(demoService)
        .generate();
  }

  public static void main(String[] args) throws Exception {
    SpringApplication.run(GrahpQLDemo.class, args);
  }

}

Приступаем к работе

Было просто добавить аннотации graphql-spqr к нашим существующим объектам доступа к данным JPA/MongoDB (DAO). На самом деле, если вы используете одни и те же имена, в этом даже нет необходимости, так как они будут подобраны автоматически. В качестве альтернативы, если вы хотите отделить DAO от определения GraphQL, вы можете определить набор объектов передачи данных (DTO) и использовать их. Это может дать вам больше гибкости, если вы не можете изменить свой уровень DAO. Мы представили типы в GraphQL, добавив метод корневого запроса к каждой службе, т. Е.:

package io.committed.query;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import io.committed.dao.repository.DemoRepository;
import io.committed.dto.Document;
import io.leangen.graphql.annotations.GraphQLQuery;

@Component
public class DocumentService {

  @Autowired
  DemoRepository repository;

  @GraphQLQuery(name = "allDocuments", description="Get all documents")
  public List getDocuments() {
    return repository.findAll();
  }
}

Аргументы могут быть добавлены к этим методам для фильтрации, ограничения и т. Д., И при использовании потоков они могут быть возвращены напрямую:

@GraphQLQuery(name = "allDocuments", description="Get all documents")
  public Stream getDocuments(
      @GraphQLArgument(name = "limit", defaultValue = "0") int limit) {
    Stream stream = repository.streamAll();
    if (limit > 0) {
      stream = stream.limit(limit);
    }

    return stream;
  }

Аналогично, мы можем получить конкретный документ по идентификатору и напрямую вернуть Необязательный :

@GraphQLQuery(name = "document")
  public Optional getDocument(@GraphQLArgument(name = "id") String id) {
    return repository.findById(id);
  }

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

package io.committed.dto;

import io.leangen.graphql.annotations.GraphQLId;
import io.leangen.graphql.annotations.GraphQLQuery;
import lombok.Data;

@Data
public class Document {

  @GraphQLId
  private String id;
  private String content;

  @GraphQLQuery(name = "length")
  public int length() {
    return content.length();
  }

}

Это откроет поле длина в классе Документ . Этот метод вызывается только по запросу запроса, поэтому клиенту не нужно платить штраф за любые вычисления, которые ему не нужны. Такие методы также позволяют клиенту экономить на передаче данных, заставляя сервер выполнять вычисления и передавая только результат.

Получение графиков

Реальная мощь GraphQL заключается в возможности просматривать типы данных по их объединяющим свойствам. Например, если у меня есть сущности, извлеченные из документа, я хочу иметь возможность запрашивать сущности, содержащиеся в документе. Если они уже сохранены в вашем объекте документа, это тривиально, однако они могут храниться в другой таблице или коллекции в вашей базе данных. Чтобы внедрить сущности в документ, мы добавляем следующее:

@GraphQLQuery(name = "entities")
  public Stream getByDocument(@GraphQLContext Document document) {
    return repository.getByDocumentId(document.getId());
  }

где аннотация @graphqlcontext предоставляет логику связывания для построения схемы.

Получение запроса

Вы можете запрашивать с помощью графического пользовательского интерфейса, размещенного на //graphql/график или отправлять HTTP-запросы на /graphql и получите схему из /schema.json , я уверен, что все это тоже настраивается. Вы также можете использовать GraphQL внутренне, например, создав Службу запросов :

package io.committed.query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import graphql.ExecutionResult;
import graphql.GraphQL;
import graphql.schema.GraphQLSchema;

@Service
public class QueryService {

  private final GraphQL graphQL;

  @Autowired
  public QueryService(GraphQLSchema graphQLSchema) {
    graphQL = GraphQL.newGraphQL(graphQLSchema).build();
  }

  public ExecutionResult query(String query) {
    return graphQL.execute(query);
  }

}

Или предоставив объект GraphQL в качестве компонента.

Становится лучше

Мы смогли запустить и запустить быструю конечную точку GraphQL менее чем за день на наших существующих объектах DAO, предоставляя мощный механизм запросов для клиентов. В ходе этого расследования мы обнаружили и сообщили об ошибке в graphql-spqr и получили быстрый ответ от автора . Похоже, что эта экосистема будет быстро развиваться, поэтому предложения по улучшению graphql-spqr следующие:

  • Возможность игнорировать определенные поля
  • Готовая поддержка ограничения и фильтрации
  • Поддержка graphql-java v5

В целом, это очень перспективный путь для быстрой интеграции GraphQL в существующий сервер spring-boot.

Оригинал: “https://dev.to/committedsw/first-impressions-with-graphql-in-java-5c82”