当前位置: 首页 > 工具软件 > graphql-spqr > 使用案例 >

GraphQL:整合Spring Boot

燕扬
2023-12-01

GraphQL:整合Spring Boot

GraphQL在Java中的应用要解决的第一个问题便是如何根据Java Bean自动生成GraphQL Schema,定义多套基本上是不可接受的,在现有加一些注解还是能忍的。

1. SQL解决方案

关系型数据库的解决方案已经做得比较好了,目前Yahoo/Elide应该是做得最好的,结合elide-spring-boot-starter可以轻松完成。虽然文档不详细,但是对基本了解是够了,特点如下(如果考虑其它方案可以一一对比,应该是比elide在便利性上要差一些):

  1. 由Java Bean自动生成GraphQL的Schema,无需额外注解;

  2. 可以限定顶级访问对象(隐藏一些数据不在顶层);

    @Include(rootLevel = true)
    
  3. 无需Repository/Service之类操作DB的代码,结合了RQL,让filter操作更简单;

  4. 定义了比较完善的操作,共6种

  5. 其它:有权限管理,实现依据Relay规范

可以看完这些再来跟一些其它方案比较比较(不比了,实在是没得比,Yahoo毕竟曾经是一流互联网企业)。

用例可参考GraphQL初探:Java服务示例及Yahoo/Elide文章中的3.2部分。

2. NOSQL解决方案

2.1 Elide

很不幸,Elide只是社区大概有句“也许可以通过Hibernate OGM实现”,简单做了尝试,没能做出一个可用的来。

2.2 GraphQL-SPQR

GraphQL-SPQR: Java 8+ API for rapid development of GraphQL services

注意:GraphQL-SPQR可不是只能做NOSQL,放在这里只是说灵活性比较好,可以把组件拆解让NOSQL方案也能使用。

特点:

  1. 对代码没有侵入性
  2. 只通过Service代码注解来生成GraphQL Schema中的各种更新、查询,不影响原有代码的功能

3 基于GraphQL-SPQR的示例

示例代码见du00cs/graphql-demo(贴代码是不可能的),有一些需要注意的点:

Java bean定义预期是有嵌套、有集合的,记得关掉@Entity注解,避免hibernate扫描报mapping错误。

import lombok.Data;

import javax.persistence.*;
import java.util.List;

@Data
// @Entity 别加,加了之后hibernate会按关系表扫描,报列无法mapping的错误
@Table(name = "places")
public class Place {
    @Id
    @GeneratedValue
    String id;
    String category;
    String name;
    List<String> alias;
    List<Level> levels;

    public Place(String name, List<String> alias) {
    this.name = name;
    this.alias = alias;
    }
}
import lombok.Data;

@Data
public class Level {
    String name;
}

需要关注的核心都在Service代码的注解中

import io.leangen.graphql.annotations.GraphQLMutation;
import io.leangen.graphql.annotations.GraphQLQuery;
import io.leangen.graphql.spqr.spring.annotations.GraphQLApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;

@GraphQLApi
@Service
public class PlaceService {
    @Autowired PlaceRepository repo;

    @GraphQLMutation
    public Place createPlace(Place place) {
        return repo.save(place);
    }

    @GraphQLQuery
    public Collection<Place> allPlaces() {
        return repo.findAll();
    }
}

4. 一些可以改进的点

  1. SPQR方案中一个比较烦的是Query操作要定义大量函数,这里可以学习Elide中的RQL方案,简化查询;
  2. Elide打通Hibernate OGM:虽然有点麻烦,但是打通还是很有意义的,仍然值得尝试的。好的方案忍不住想让它变得更好。
 类似资料: