Spring Boot + GraphQL 才是 API 的未来!

点击上方“芋道源码”,选择“设为星标

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 10:33 更新文章,每天掉亿点点头发...

源码精品专栏

 

来源:blog.csdn.net/x763795151/
article/details/117604505

b3b1f7b61e818bfab55b2f099b2bca93.png


前言

在浅尝GraphQL一文描述了GraphQL及基本使用,本文提供一个基本示例,描述如何基于spring boot的web项目快速应用。

graphql-java的官方文档:Getting started with GraphQL Java and Spring Boot,提供了相关依赖用以快速配置,但是个人真心不建议使用这个库及相关配置方式来搭建脚手架,在实际开发中,业务比较复杂的时候,会导致需要配置的业务代码比较多也比较繁琐,相对下面这种方式,代码复杂性比较高。

本文提供一种更灵活快捷的方式,在spring boot项目中快速应用开发。使用的依赖也和上面官方提供的都不一样,请注意区分。

推荐下自己做的 Spring Boot 的实战项目:

https://github.com/YunaiV/ruoyi-vue-pro

快速开始

创建spring boot工程

通过Spring Initializr快速搭建,我选的jdk版本及spring boot版本,如下所示,其它版本未做兼容性测试。

f4feec0780cf0bb776d727730554fbf4.png

点击下方的Generate按钮:

f90e94580bc3cf89bcbe9329dd73fa50.png

打开工程结构如下,我将application.properties删除了替换成applicaiton.yml,因为我个人比较喜欢yaml的配置方式:

0317a01b2ecd776ac448df67be32c0b8.png

引入相关依赖

pom.xml配置如下:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.4.6</version>
  <relativePath/> <!-- lookup parent from repository -->
 </parent>
 <groupId>com.xuxd</groupId>
 <artifactId>graphql.demo</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>graphql.demo</name>
 <description>GraphQL Demo project for Spring Boot</description>
 <properties>
  <java.version>1.8</java.version>
  <maven.compiler.source>1.8</maven.compiler.source>
  <maven.compiler.target>1.8</maven.compiler.target>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <lombok.version>1.18.20</lombok.version>
  <graphql-java-tools.version>11.0.1</graphql-java-tools.version>
  <gson.version>2.8.7</gson.version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter</artifactId>
  </dependency>
 
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
 
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
  </dependency>
 
  <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>${lombok.version}</version>
   <scope>provided</scope>
  </dependency>
 
  <dependency>
   <groupId>com.graphql-java-kickstart</groupId>
   <artifactId>graphql-java-tools</artifactId>
   <version>${graphql-java-tools.version}</version>
  </dependency>
 
  <dependency>
   <groupId>com.google.code.gson</groupId>
   <artifactId>gson</artifactId>
   <version>${gson.version}</version>
  </dependency>
 </dependencies>
 
 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>
 
</project>

初始化GraphQL实例

我们将创建一个GraphQL实例并将其注册到spring容器中,代码如下:

创建一个GraphQLProvider类:

@Component
public class GraphQLProvider {
 
    private GraphQL graphQL;
 
    @Autowired
    private IItemService itemService;
 
    @Bean
    public GraphQL graphQL() {
        return graphQL;
    }
 
    @PostConstruct
    public void init() throws IOException {
        GraphQLSchema graphQLSchema = SchemaParser.newParser()
            .file("graphql/base.graphqls")
            .resolvers(new Query(), new Mutation())
            .file("graphql/item.graphqls")
            .resolvers(new ItemResolver(itemService))
//            .file("book.graphqls")
//            .resolvers(new BookResolver())  //其它定义照上面的示例,继续增加
            .build().makeExecutableSchema();
 
        this.graphQL = graphQL.newGraphQL(graphQLSchema).build();
    }
 
}

关于*.graphqls或者对应的Resolver如ItemResolver,可以参看浅尝GraphQL相关描述,这里只是作了微调整,相关代码如下:

base.grqphqls

schema {
    # 查询
    query: Query
    # 更新
    mutation: Mutation
}
 
type Query {
    version: String
}
 
type Mutation {
    version: String
}

item.graphqls

> 推荐下自己做的 Spring Cloud 的实战项目:
>
> <https://github.com/YunaiV/onemall>

# 定义一个查询类型
extend type Query {
    queryItemList: ItemList  # 定义查询项目列表
    queryById(id: ID): Item
}
 
extend type Mutation {
    updateName(param: Param): Item
}
 
# 定义项目字段
type Item {
    id: ID!
    code: String!
    name: String!
}
 
type ItemList {
    itemList: [Item!]!  #获取项目列表
    total: Int!      # 获取项目总数
}
 
input Param {
    id: ID!
    name: String!
}

ItemResolver

public class ItemResolver implements GraphQLQueryResolver, GraphQLMutationResolver {
 
    private IItemService itemService;
 
    public ItemResolver(IItemService itemService) {
        this.itemService = itemService;
    }
 
    // 对应item.graphqls里的queryItemList
    public ItemList queryItemList() {
        return itemService.queryItemList();
    }
 
    public Item queryById(Long id) {
        return itemService.queryById(id);
    }
 
    public Item updateName(Param param) {
        return itemService.updateName(param);
    }
}

相关业务代码比较多,就不一一贴了。

提供API

我们需要暴露一个接口来接收请求,并作相关处理,也只需提供一个接口即可。因此我们创建一个Controller:GraphqlController.

@RestController
@RequestMapping("/graphql")
@Log
public class GraphqlController {
 
    @Autowired
    private GraphQL graphQL;
 
    @PostMapping
    public Object execute(@RequestBody GraphqlRequest request) {
        ExecutionInput executionInput = ExecutionInput.newExecutionInput()
            .query(request.getQuery())
            .variables(request.getVariables())
            .build();
        Map<String, Object> result = new HashMap<>();
 
        ExecutionResult executionResult = graphQL.execute(executionInput);
        List<GraphQLError> errors = executionResult.getErrors();
 
        if (errors != null && !errors.isEmpty()) {
            result.put("errors", errors);
            return result;
        }
        return executionResult.getData();
    }
}

到这一步,其实基本功能都已配置完成,可以启动项目进行相关测试了。

整个项目的代码结构如下,我尽量用了一个比较常规的web项目结构(controller,service,dao等):

171514bc3bae1aeeb0416889e5f1e65c.png

测试

示例中总共提供了3个接口,两个查询一个更新,分别进行测试:

ItemList queryItemList();
 
Item queryById(Long id);
 
Item updateName(Param param);

查询所有项目列表(只获取每个项目的编码和名称,以及列表总数):

d43c3d991a9dead9aea71db9707b4457.png

根据ID查询,获取项目的id和名称

d9d66b6834de5891d860454a1ed78557.png

更新指定ID的项目名称

我们项目Id为1编码为test的项目修改为“java项目”

c075bf833c66e297f25ef468109aa929.png

再查询一下,可以看到结果更新了:

60326402e44014fc7b661e202ec926b2.png

结束语

这样整个项目的GraphQL相关的基本配置已经完成,可以进行业务开发了。

关于示例的完整代码,我提交到了github,感兴趣可以下载下来看下,地址:

https://github.com/xxd763795151/graphql.demo



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

0161df0f6ec4a74dfe1086fe0a41552d.png

已在知识星球更新源码解析如下:

43ecb633ffcb1125080b819454640527.png

a8dafaed740ea9d90d20a644a2a3466b.png

af3b1cbae4b0d8fbb4a106b9f4119e5b.png

78e81782e9c77a09b5c7c8b077285cb3.png

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值