Spring Boot + GraphQL 才是 API 的未来!

简介: 前言在浅尝GraphQL一文描述了GraphQL及基本使用,本文提供一个基本示例,描述如何基于spring boot的web项目快速应用。graphql-java的官方文档:Getting started with GraphQL Java and Spring Boot,提供了相关依赖用以快速配置,但是个人真心不建议使用这个库及相关配置方式来搭建脚手架,在实际开发中,业务比较复杂的时候,会导致需要配置的业务代码比较多也比较繁琐,相对下面这种方式,代码复杂性比较高。

前言

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


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


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


快速开始

创建spring boot工程

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

image.png

点击下方的Generate按钮:

image.png

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

image.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

# 定义一个查询类型
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等):

image.png

测试

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

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

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


image.png


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


image.png


更新指定ID的项目名称


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


image.png


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


image.png

结束语

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


相关文章
|
4月前
|
前端开发 Java API
利用 Spring WebFlux 技术打造高效非阻塞 API 的完整开发方案与实践技巧
本文介绍了如何使用Spring WebFlux构建高效、可扩展的非阻塞API,涵盖响应式编程核心概念、技术方案设计及具体实现示例,适用于高并发场景下的API开发。
396 0
|
3月前
|
人工智能 Java 机器人
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
Spring AI Alibaba集成Ollama,基于Java构建本地大模型应用,支持流式对话、knife4j接口可视化,实现高隐私、免API密钥的离线AI服务。
2853 1
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
|
6月前
|
缓存 安全 API
RESTful与GraphQL:电商API接口设计的技术细节与适用场景
本文对比了RESTful与GraphQL这两种主流电商API接口设计方案。RESTful通过资源与HTTP方法定义操作,简单直观但可能引发过度或欠获取数据问题;GraphQL允许客户端精确指定所需字段,提高灵活性和传输效率,但面临深度查询攻击等安全挑战。从性能、灵活性、安全性及适用场景多维度分析,RESTful适合资源导向场景,GraphQL则适用于复杂数据需求。实际开发中需根据业务特点选择合适方案,或结合两者优势,以优化用户体验与系统性能。
|
4月前
|
缓存 Java API
Spring WebFlux 2025 实操指南详解高性能非阻塞 API 开发全流程核心技巧
本指南基于Spring WebFlux 2025最新技术栈,详解如何构建高性能非阻塞API。涵盖环境搭建、响应式数据访问、注解与函数式两种API开发模式、响应式客户端使用、测试方法及性能优化技巧,助你掌握Spring WebFlux全流程开发核心实践。
810 0
|
6月前
|
Java API 网络架构
基于 Spring Boot 框架开发 REST API 接口实践指南
本文详解基于Spring Boot 3.x构建REST API的完整开发流程,涵盖环境搭建、领域建模、响应式编程、安全控制、容器化部署及性能优化等关键环节,助力开发者打造高效稳定的后端服务。
933 1
|
8月前
|
存储 人工智能 Java
Spring AI与DeepSeek实战四:系统API调用
在AI应用开发中,工具调用是增强大模型能力的核心技术,通过让模型与外部API或工具交互,可实现实时信息检索(如天气查询、新闻获取)、系统操作(如创建任务、发送邮件)等功能;本文结合Spring AI与大模型,演示如何通过Tool Calling实现系统API调用,同时处理多轮对话中的会话记忆。
1596 57
|
5月前
|
缓存 边缘计算 前端开发
从业务需求到技术栈:电商API选型RESTful还是GraphQL?这5个维度帮你决策
在数字经济时代,电商平台的竞争已延伸至用户体验与系统效能。作为连接前后端及各类服务的核心,API接口的架构设计至关重要。本文对比RESTful与GraphQL两大主流方案,从电商场景出发,分析两者的技术特性、适用场景与选型逻辑,帮助开发者根据业务需求做出最优选择。
|
9月前
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
|
11月前
|
XML Java 应用服务中间件
Spring Boot 两种部署到服务器的方式
本文介绍了Spring Boot项目的两种部署方式:jar包和war包。Jar包方式使用内置Tomcat,只需配置JDK 1.8及以上环境,通过`nohup java -jar`命令后台运行,并开放服务器端口即可访问。War包则需将项目打包后放入外部Tomcat的webapps目录,修改启动类继承`SpringBootServletInitializer`并调整pom.xml中的打包类型为war,最后启动Tomcat访问应用。两者各有优劣,jar包更简单便捷,而war包适合传统部署场景。需要注意的是,war包部署时,内置Tomcat的端口配置不会生效。
2726 17
Spring Boot 两种部署到服务器的方式
|
9月前
|
XML 网络协议 API
从cURL到GraphQL:不同API类型概述
本文概述了不同API类型及其应用,帮助开发人员选择合适的工具。cURL是强大的命令行工具,适用于调试和自动化;RESTful API基于HTTP方法,适合Web服务和微服务架构;SOAP用于企业级应用,提供高安全性;GraphQL通过精确查询减少数据传输;WebSocket支持实时通信,适用于低延迟场景。了解这些API的特点和优势,有助于构建高效、可扩展的应用程序。