Java中GraphQL的第一印象

GraphQL-Java

GraphQL is an open query language for exposing data in a flexible way. It was developed by Facebook and now in production use in many projects. The main concepts are that GraphQL describes the data available and then the consumer can ask for what they need. All using the same endpoint and language.

We are investigating its use to expose natural language processing results to replace, or augment, REST.

Java生态系统

GraphQL is programming language agnostic and different implementations exist in many languages for this project we are using Java and Spring Boot so the natural choice is graphql-java. It may not be the only java implementation but it is certainly the most active at this time. This core project stays true to the specification and there are a number of supporting projects to ease integration and use.

方法

In GraphQL you need to declare your data schema so clients can introspect the system and query correctly. However, the schema needs to be an accurate representation of your underlying data classes. While you could create both of these things manually, generating one from the other will reduce effort and errors. One approach is to define your schema and generate the data classes. This approach is provided by graphql-apigen and graphql-java-tools. While this approach could be very useful if you have a new project with a strict schema specification, we already have data classes. Therefore, we take the classes-first approach and generate the schema. There is a graphql-java-annotations project based on this approach, however, development of it seems to have stopped and the community seems to be moving towards graphgql-spqr (pronounced “speaker”). It looks likely that this will become the official graphql-java class-first approach.

入门

It was very easy to get started using the graphql-spring-boot. This gives:

  • A graphql-java servlet, to serve the schema, and accept GET and POST GraphQL requests
  • A GraphiQL UI, for writing and executing GraphQL queries against the published schema.
  • grapghql-java-tools schema first
  • graphql spring common class first

我们选择不使用后者,并通过提供一个简单的方法来添加graphql-spqrgraphql.schema.GraphQLSchema使用graphql-spqr及其上的注释生成的Bean演示服务以及使用的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<Document> getDocuments() {
    return repository.findAll();
  }
}

可以将参数添加到这些方法中以进行过滤,限制等,如果使用Streams,则可以直接返回这些参数:

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

    return stream;
  }

同样,我们可以通过id获取特定的文档,然后直接返回可选的:

@GraphQLQuery(name = "document")
  public Optional<Document> 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的真正能力来自通过联接属性遍历数据类型的能力。 例如,如果我从文档中提取实体,那么我希望能够查询文档中包含的实体。 如果这些已经存储在您的Document对象中,那么这是微不足道的,但是,它们可能存储在数据库中的其他表或集合中。 要将实体嵌入文档中,我们添加以下内容:

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

在哪里@GraphQLContext批注提供了建立架构的链接逻辑。

获取查询

您可以使用托管在以下位置的GraphiQL UI进行查询/ graphiql或发送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对象作为bean。

越来越好

We were able to get a quick GraphQL endpoint up and running in less that a day on our existing DAO objects providing a powerful querying mechanism for clients. During this investigation, we uncovered and reported a bug in graphql-spqr and got a rapid response from the author. It looks likely that this ecosystem will develop fast, out suggestions for improvements to graphql-spqr are:

  • 能够忽略某些字段开箱即用的限制和过滤支持支持graphql-java v5

总体而言,这是将GraphQL快速集成到现有spring-boot服务器中的非常有希望的途径。

from: https://dev.to//committedsw/first-impressions-with-graphql-in-java-5c82

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
graphql-java 是 GraphQLJava 实现。这个库的目标是用于真实的生产环境。graphql-java 解析和执行查询 GraphQL 。它并不真正获取任何数据的:数据来源于执行回调或提供静态数据。graphql-java 的 "hello world":import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; import static graphql.Scalars.GraphQLString; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; import static graphql.schema.GraphQLObjectType.newObject; public class HelloWorld {     public static void main(String[] args) {         GraphQLObjectType queryType = newObject()                         .name("helloWorldQuery")                         .field(newFieldDefinition()                                 .type(GraphQLString)                                 .name("hello")                                 .staticValue("world")                                 .build())                         .build();         GraphQLSchema schema = GraphQLSchema.newSchema()                         .query(queryType)                         .build();         Map result = new GraphQL(schema).execute("{hello}").getData();         System.out.println(result);         // Prints: {hello=world}     } } 标签:graphql
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值