Spring Boot使用GraphQL开发Web API

2023/9/30 17:11:09

目录

  • 前言
  • Spring Boot中GraphQL的实现方案

前言

传统的Restful API 存在诸多的问题,首先它无法控制返回的字段,前端也无法预判后端的返回结果,另外不同的返回结果对应不同的请求地址,这就导致了多次请求的问题。而GraphQL正是基于这样的背景而构建出来的API查询语言,相对于传统Restful API 它具有以下几个优点:

  • 灵活性:GraphQL 可以根据客户端的需求灵活地查询数据,而不是像 RESTful API 那样返回固定结构的数据。

  • 减少网络请求:GraphQL 允许客户端在一次请求中获取多个资源,这有助于减少网络请求的数量和提高性能。

  • 强类型:GraphQL 有一种强类型系统,客户端可以在编译时检测到查询中的错误,这有助于减少运行时错误。

  • 可缓存:GraphQL 具有可缓存性,这意味着服务器可以缓存查询的结果,从而提高性能和可伸缩性。

  • 文档化:GraphQL 具有自我文档化的能力,使得开发者可以快速了解 API 的结构和功能。

Spring Boot中GraphQL的实现方案

如果后端语言为Java,那么GraphQL Java则是实现GraphQL的基础库。另外Spring已经整合了GraphQL,如果项目中使用了Spring,那么更加推荐Spring GraphQL。

Spring GraphQL的开发总体分为如下几个步骤

  1. 添加 Spring GraphQL 依赖项

在您的项目中添加 Spring GraphQL 依赖项。您可以通过 Maven 或 Gradle 等构建工具来添加依赖项。例如,如果您使用 Maven,则可以添加以下依赖项

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-graphql</artifactId>
        </dependency>
  1. 定义 GraphQL Schema

在您的应用程序中定义 GraphQL Schema。Schema 定义了可查询的类型和字段。您可以使用 SDL(Schema Definition Language)或编程方式定义 Schema。

对于Spring Boot 工程来说schema文件放到resources/graphql/目录下,文件名后缀graphqls,下面是我定义一个的简单的schema.graphqls。

它指定了两个查询实现,author(id:Int)表示通过id查询Author,allAuthors则表示查询Author数组。

schema {
    query: Query
}

type Query {
    author(id:Int): Author
    allAuthors: [Author]
}

type Author {
    id:Int
    firstName:String
    lastName:String
    email:String
    birthdate:String
}
  1. 实现RuntimeWiringConfigurer

RuntimeWiringConfigurer是实现GraphQL获取数据的核心,使用GraphQL并不能直接去掉Mybatis/Jpa这类持久层框架,从数据库获取数据仍然需要这类框架的支持。

而RuntimeWiringConfigurer则类似于Spring中的service层,它是实现基础数据的核心。

以下是一个简单示例:

@Component
public class AuthorWiring implements RuntimeWiringConfigurer {

    private final AuthorRepository authorRepository;

    public AuthorWiring(AuthorRepository authorRepository) {
        this.authorRepository = authorRepository;
    }

    @Override
    public void configure(RuntimeWiring.Builder builder) {
        builder.type("Query", typeWiring -> typeWiring
                        .dataFetcher("allAuthors", environment -> authorRepository.findAll())
                        .dataFetcher("author", environment -> authorRepository.getReferenceById(environment.getArgument("id")))
    }
}

这里configure方法内部分别定义了两个DataFetcher对象,用来指定author和allAuthors查询数据的方式,可以看出依然是通过JPA去查询数据。

  1. 定义GraphQL Controller

我么定义GraphQLController用来接收web请求的入参,示例如下:

@RestController
@RequestMapping("graphql")
public class GraphQLController {

    private final GraphQL graphQL;

    @Autowired
    public GraphQLController(GraphQlSource graphQlSource) {
        graphQL = graphQlSource.graphQl();
    }

    @PostMapping("query")
    public ResponseEntity<Object> query(@RequestBody String query) {
        ExecutionResult result = graphQL.execute(query);
        return ResponseEntity.ok(result.getData());
    }
}

代码中GraphQL对象是执行查询的入口,但GraphQL只有一个私有的构造方法,所以不能直接注入,必须通过注入GraphQlSource的方式来获取GraphQL对象。

注意在GraphQL中我们只能使用String来接收参数,无法使用model对象,这是因为Graph请求参数并不是json结构。

  1. 测试Graph请求

我们创建一个graphql.http的文件,用于在idea中执行http请求

### Send POST request with json body
POST http://localhost:8080/graphql/query
Content-Type: application/json

{
  author(id: 1) {
    id
    firstName
    lastName
    birthdate
  }
}

### Send POST request with json body
POST http://localhost:8080/graphql/query
Content-Type: application/json

{
  allAuthors {
    id
    firstName
    lastName
    birthdate
  }
}

运行author(id: 1) 的查询,可以看到正常返回结果了。如果我们只需要 firstName和lastName两个字段,那么在请求入参中直接去掉id和birthdate就好了,而不用改动任何后端代码。

完整项目已上传github 👉 graphql-demo,有问题您可在博客下面留言,欢迎交流。


http://www.jnnr.cn/a/369248.html

相关文章

9.网络爬虫—MySQL基础

网络爬虫—MySQL基础MySQL安装教程MySQL登录Mysql数据库操作显示数据库创建数据库删除数据库查询数据库使用数据库Mysql数据类型Mysql数据表创建Mysql增删查改PyMysql安装Python的MySQL库连接数据库增添字段操作游标PyMysql插入PyMysql查询PyMysql更新PyMysql删除前言&#xff…

生成式 AI 背后的共同框架:Stable Diffusion、DALL-E、Imagen

前言 如果你对这篇文章感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 框架 这些生成式 AI 的整体功能为&#xff1a;输入「文字」&#xff0c;返回「图像」&#xff0c;即 Text-to-image Gener…

计算机发展史之阿达·洛芙莱斯

你一定想不到世界上最早的程序员竟然是一位女士&#xff0c;而且还有专门的编程语言为了纪念她而命名&#xff0c;她就是阿达洛芙莱斯&#xff08;Ada Lovelace&#xff09; 奥古斯塔阿达拜伦是她的原名&#xff0c;因为嫁给威廉金后晋封为洛芙莱斯伯爵&#xff0c;而后改的名字…

R -- 卡方检验--原理及应用

1.单样本方差同质性检验 2.适合性/拟合优度/吻合性检验 或者公式书写如下&#xff1a; 图片来源&#xff1a;https://www.bilibili.com/opus/730576389651038260?fromsearch&spm_id_from333.337.0.0 例题 3.独立性检验 如何理根据列联表推算论值 E11 sum(Row1) * sum(…

(九)大数据实战——hadoop集群的历史服务器配置与日志聚集

前言 前面的章节我们已经介绍过了关于hadoop集群部署的内容&#xff0c;延续上一节的内容。本节我们主要介绍一下关于hadoop集群历史服务器的配置与启动&#xff0c;方便我们查看hadoop操作过程中的一些任务执行情况。同时我们也配置一下hadoop集群的日志聚集功能&#xff0c;…

linux系统安装JDK(我的系统是ubunut20.04)

一、下载jdk包 # 下载解压wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gztar -zxvf jdk-17_linux-x64_bin.tar.gz # 将jdk-17改名为javamv jdk-17 java# 拷贝到/usr/local目录下sudo cp -rap java /usr/local 二、添加环境变量 # 进入profile文…

信息系统项目管理师第四版知识摘编:第13章 项目资源管理​

第13章 项目资源管理​ 项目资源管理包括识别、获取和管理所需资源以成功完成项目的各个过程&#xff0c;这些过程有助于确保项目经理和项目团队在正确的时间和地点使用正确的资源。​ 13.1管理基础​ 13.1.1相关术语和定义​ 1项目团队​ 项目团队是执行项目工作&#xf…

linux入门---程序地址空间

之前学习的地址空间 在之前的学习中我们知道操作系统将内存划分为好几个区域&#xff0c;比如说栈区&#xff0c;堆区&#xff0c;未初始化区&#xff0c;已初始化区&#xff0c;代码区&#xff0c;每个区的大小不同所对应的功能也不同&#xff0c;并且在内存中每个字节大小的…

还在用xmind破解版?快来康康这个,墙裂推荐

我之前一直在用XMind破解 首先不是不支持&#xff0c;只是囊中有点羞涩....... 言归正传&#xff0c;我很是特别喜欢XMind的这些小功能&#xff0c;简直是神助攻 XMind 推荐指数&#xff1a;☆☆☆☆☆ 点击直达 >>XMind.cn 01 一键提取风格 魔力值 No.1 的非创建风…

【进阶C语言】各大常用库函数的模拟实现

前言 今天恒川带给大家的是平常应用的库函数&#xff0c;恒川来给大家都模拟实现一下&#xff0c;希望对大家有帮助&#xff01;&#xff01; 各大常用库函数的模拟实现1. 模拟实现strlen2. 模拟实现strcpy3. 模拟实现strcat4. 模拟实现strstr5. 模拟实现strcmp6. 模拟实现memc…

[Java] synchronized的锁优化机制

目录 一 . 锁膨胀(锁升级) 二 . 锁消除 三 . 锁粗化 附加 : Callable 接口 ReentrantLock ReentrantLock 与 synchronized 的区别 Semaphore (信号量) CountDownLatch 多线程下使用哈希表 1. HashTable 2 .ConcurrentHashMap ConcurrentHashMap 优点 CopyOnWri…

华为交换机 链路聚合

前言 随着网络规模不断扩大&#xff0c;用户对骨干链路的带宽和可靠性提出了越来越高的要求。在传统技术中&#xff0c;常用更换高速率的接口板或更换支持高速率接口板的设备的方式来增加带宽&#xff0c;但这种方案需要付出高额的费用&#xff0c;而且不够灵活。 采用链路聚合…

Java锁深入理解2——ReentrantLock

前言 本篇博客是《Java锁深入理解》系列博客的第二篇&#xff0c;建议依次阅读。 各篇博客链接如下&#xff1a; Java锁深入理解1——概述及总结 Java锁深入理解2——ReentrantLock Java锁深入理解3——synchronized Java锁深入理解4——ReentrantLock VS synchronized Java锁…

Set的底层实现

一、二分搜索树 最核心的操作在于查找 a.是一棵二叉树 b.若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值. c.若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值. 特点&#xff1a; 中序遍历为递增排序 二、哈希函数 哈希函数…

01 | Qt基本介绍及环境搭建

1 简介 1.1 简介 Qt 是一个1991年由Qt Company开发的跨平台C图形用户界面应用程序开发框架。它既可以开发GUI程序&#xff0c;也可用于开发非GUI程序&#xff0c;比如控制台工具和服务器。 2014年4月&#xff0c;跨平台集成开发环境Qt Creator 3.1.0正式发布&#xff0c;实现…

C++源码剖析——deque

前言&#xff1a;之前看过侯老师的《STL源码剖析》但是那已经是多年以前的&#xff0c;现在工作中有时候查问题和崩溃都需要了解实际工作中使用到的STL的实现。因此计划把STL的源码再过一遍。   摘要&#xff1a;本文描述了llvm中libcxx的deque的实现。   关键字&#xff1…

REDIS21_缓存双写一致方案、先更新数据库再删除缓存

文章目录①. 什么是缓存双写一致②. 先更新数据库,再更新缓存③. 先删除缓存,再更新数据库④. 先更新数据库,再删除缓存①. 什么是缓存双写一致 ①. 缓存双写一致性,谈谈你的理解 如果redis中有数据,需要和数据库中的值相同如果redis中无数据,数据库中的值要是最新值 ②. 什么…

MarTech老将如何焕发新生?数据猿直播干货分享

‍数据智能产业创新服务媒体——聚焦数智 改变商业MarTech一直备受关注&#xff0c;然而2022年的MarTech市场却不尽如人意。据最新数据显示&#xff0c;2022年&#xff0c;MarTech行业的融资总额为302.43亿元人民币&#xff0c;与2021年相比下降了31.7%。可见后疫情时代&#…

windows通过浏览器访问noVNC(基于web的远程桌面)

目录 一、什么是VNC 和 noVNC&#xff1f; 二、Windows10安装及配置noVNC 2.0、注释 2.1、下载UltraVNC 2.2、下载Node.js 2.3、下载安装git 2.4、创建一个存放文件的文件夹 2.5、安装ws、optimist、mime-types模块&#xff08;执行websockify.js文件所需&#xff09; …

双master节点+keepalived方式部署K8s 1.18.20

相关部署方式也挺多&#xff0c;自己采用双master节点单node节点方式&#xff0c;并且采用keepalived部署1.18.20版本&#xff0c;中间也出现过相关小问题&#xff0c;但都一一处理&#xff0c;记录以给需要的同仁们参考&#xff0c;希望大家都可以一起学习交流&#xff01;&am…
最新文章