选择 REST ,还是 GraphQL

在本文中,简单比较 REST 和 GraphQL 的优点和缺点,以便您可以决定哪种 API 架构最适合您的项目

当我们要创建数据驱动的 Web 或移动应用程序,需要开发后台 API,通过它可以从后端服务器来访问或操作数据。目前最流行的 API 架构是 REST,尽管 REST 广为人知并且通常易于使用,但它也有一些缺点,主要是包括冗余数据的过度获取、扩展效率低下。

GraphQL 是一种新型 API 架构,其设计比 REST 更灵活、更高效,具有声明式数据获取等功能。虽然 GraphQL 已经变得相当流行,但它并没有取代 REST,因为一些用户发现它更难使用,并认为它是一个过度设计的解决方案,特别是对于较小的应用程序来说。

在本文中,将深入探讨 REST 和 GraphQL 的优缺点,以便您可以决定哪种 API 架构最适合您的项目。

REST

当前应用程序开发中 API 的主流架构是 REST,大多数后端框架将实现 REST。REST API 通常使用 HTTP 方法通过称为(例如GET /api/articles )的 URL 集合进行调用POST /api/articles。

Demo

以创建一个博客网站为例。在主页上,显示最新文章的摘要,包括标题、图像和简短说明。要为此提供数据,需要在后端服务器上设置一个 REST API,GET/api/articles它将以 JSON 数组的形式返回所需的数据,如下例所示:

// GET /articles
[
  {
    "id": 1,
    "title": "REST is Awesome",
    "image": "https://myrestblog.com/img/dsh9a89.png",
    "description": "The benefits of REST"
  },
  {
    "id": 2,
    "title": "How REST Works",
    "image": "https://myrestblog.com/img/33szad2.png",
    "description": "Learn about REST"
  }
]

REST优点

REST 在很大程度上击败了 SOAP、WebService、XML 等较旧的 API 协议,并且尽管出现了 GraphQL 等较新的替代方案,但仍继续流行,其主要原因为:

易于实施

在 Web 服务器应用程序中设置 REST 很简单,尤其是当它使用 Java的 Springcloud或 Python 的 Requests 等 API 框架时。例如,使用 MongoDB 在 Express 应用程序中设置 REST 端点/articles就像调用数据库并将记录返回为 JSON 一样简单,如下所示:

python:

app.get('/api/articles', async (req, res) => {
    try {
        const articles = await db.articles.find() res.json(articles)
    } catch (err) {
        res.status(500).send(err)
    }
})
广泛理解和协同开发

无论 GraphQL 是否优于 REST,大多数开发人员都会同意,当您使用自己所知道的知识时,开发效率会更高。截至 2022 年,如果您有多个开发人员在开发您的应用程序,或者您有公共 API,则大多数消费者将熟悉 REST,GraphQL 还不能说同样的情况,哈哈~~。

REST 的缺点

要理解为什么创建 GraphQL,我们需要首先看看 REST 的缺点

过度获取

回到博客的示例,假设创建了一个移动网站。与桌面版本一样,在主页上显示文章摘要。由于手机屏幕较小,这里的摘要只需要标题和图片,可以省略描述。不幸的是,由于GET /api/articles端点是固定的,移动版本description在调用 API 时仍然会收到该字段。这种低效率被称为“过度获取”,并且在发送大量数据时会成为挑战。

冗余数据效率低下

当对象包含表示相关实体的子对象时,该对象具有嵌套数据。例如,可能有一个带有嵌套评论对象的文章对象。由于实体在 REST 中被分配了自己唯一的URL,因此可能需要通过单独的 API 往返来填充嵌套数据。

例如,要获取一篇文章,我们首先使用端点GET /api/articles。要获取本文的评论,我们需要首先等待文章数据填充,以便我们知道在后续请求中需要获取哪些特定评论,如下面的代码示例所示。等待这些后续请求得到解决将增加用户在与页面交互之前必须等待的时间。

// GET /articles

[
  {
    "id": 1,
    "title": "REST is Awesome",
    "image": "https://myrestblog.com/img/dsh9a89.png",
    "description": "An article about REST",
    "comment_ids": [
      10,
      14,
      22
    ]
  },
  { ... }
]

GraphQL

REST 的低效率促使 Facebook 工程师在 2015 年创建了一种新的 API 设计,称为 GraphQL。GraphQL 迅速成为开发人员和公司的热门选择,推出了相关工具和服务的生态系统。与 REST 一样,GraphQL 不是一个特定的软件,而是 API 设计的规范。

GraphQL 工作原理

为了了解 GraphQL 的优势,快速概述它的工作原理。与 REST 不同,GraphQL 需要一个架构来告诉客户端和服务器允许通过 API 执行哪些数据和操作。它们是使用 GraphQL 模式语言定义的——一种与语言无关的简单格式,具有强大的类型系统。

Demo

Article让我们回到具有和实体的博客网站的示例Comment。在我们的 GraphQL 模式中,我们定义Article具有必需的整数id字段和title、image、 和的可选字符串字段的类型description,如下所示:

type Article {
  id: Integer!
  title: String
  image: String
  description: String
}

除了基本标量类型之外,模式对象还可以相互引用。Article例如,我们可以在类型和类型之间创建一对多关系Comment,如下所示:

type Article {
  id: Integer!
  title: String
  image: String
  description: String
  comments: [Comment]
}
type Comment {
  content: String
  article: Article
  author: Author
}

模型定义

GraphQL 模式的另一个重要用途是定义操作,其中包括读取数据的查询和写入数据的突变。在这里,我们提供了 的查询Articles,其类型为文章数组:

type Article {
  id: Integer!
  title: String
  image: String
  description: String
  comments: [Comment]
}
type Comment {
  content: String
  article: Article
  author: Author
}
type Query {
  articles: [Article]
}

GraphQL 的优点

通过对 GraphQL 的基本了解,我们现在可以了解它的主要优点。

声明式数据获取

GraphQL 的杀手级功能是声明式数据获取,客户端可以准确指定其需要的数据。这可以包括特定字段,甚至在嵌套对象内。我们之前看到,操作必须在模式上定义。不过,在这些操作中,我们可以指定希望查询返回哪些字段(最多达到架构的限制)。

例如,我们可以创建一个查询来Articles仅获取我们想要的字段,无论是否有嵌套Comments。请参阅下面的示例:

query {
  articles {
    id
    title
    image
    description
    comments {
      content
    }
  }
}

这是将从该查询返回的数据结构。请注意,GraphQL 响应中收到的数据将与请求它的查询具有相同的形状。

{
  "data": {
    "articles": [
      {
        "id": 1,
        "title": "REST is Awesome",
        "image": "https://restblog.com/img/dsh9a8.png",
        "description": "An article about REST",
        "comments": [
          {
            "content": "GraphQL is better!"
          },
          { ... }
        ]
      }
    ],
    ...
  }
}

通过这种方式,GraphQL 消除了过度获取和对嵌套数据的顺序调用的需要。

鲁棒性

由于强类型化和预定义查询的要求,GraphQL 可以提供开箱即用的验证和类型检查。反过来,这意味着 GraphQL 本质上是自记录的。一旦字段、类型或查询发生变化,基于模式的文档就可以自动更新。

版本控制

每次应用程序发生变化时,API 也可能需要更改。例如,假设我们决定将实体description中的字段重命名Article为blurb. REST 通过提供多个版本来处理这个问题,例如/api/v1,api/v2这对于 API 开发人员和消费者来说都是很麻烦的。使用 GraphQL,可以从架构中删除已弃用的字段,而不会影响现有查询。这为应用程序提供了对新功能的持续访问,并鼓励更清洁、更易于维护的服务器代码。

GraphQL 的缺点

虽然 GraphQL 为 REST 的缺点提供了一个优雅的解决方案,但请考虑一下 GraphQL 面临的一些批评。

取舍权衡困惑

一些开发人员认为 GraphQL 正在解决的问题常常被夸大了。例如,对于大多数小型应用程序来说,如果过度获取的几个字节的数据进入有效负载,这可能并不重要。

更难合作

另一个批评是 GraphQL 实现最终比 REST 更难编码,它还为新用户提供了更困难的学习曲线。

难以缓存

最后,GraphQL 经常因更难以缓存而受到批评,REST 客户端可以获得 HTTP 缓存的好处,因为所有端点都是 URL,而 GraphQL 客户端需要实现自己的自定义解决方案,如使用本地缓存,譬如redux-persit、localforage

结论

虽然 REST 架构在过去十年中主导了 Web 开发,但它对设置端点的使用使其有些不灵活且低效。GraphQL 通过提供严格类型的模式语言来解决这些问题,消费者可以根据需要进行查询。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/121617.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flutter的专属Skia引擎解析+用法原理

Skia是一款跨平台的2D图形库,是Google公司开发的,可以用于开发各种应用程序,如浏览器、游戏、移动应用程序等。Skia引擎的主要特点是速度快、可移植性强、占用的内存少、稳定性佳,适用于多种硬件平台。 Skia的目标是提供快速、高…

在Spring Boot中使用MyBatis访问数据库

MyBatis,这个对各位使用Java开发的开发者来说还是蛮重要的,我相信诸位在企业开发项目的时候,大多数采用的是Mybatis。使用MyBatis帮助我们解决各种问题,实际上这篇文章,基本上默认为可以跳过的一篇,但是为了…

什么是代理IP池?如何判断IP池优劣?

代理池充当多个代理服务器的存储库,提供在线安全和匿名层。代理池允许用户抓取数据、访问受限制的内容以及执行其他在线任务,而无需担心被检测或阻止的风险。代理池为各种在线活动(例如网页抓取、安全浏览等)提高后勤保障。 读完…

使用Python的requests库采集充电桩LBS位置经纬度信息

目录 一、引言 二、采集数据的流程 1、获取充电桩的URL地址 2、发送HTTP请求获取数据 3、解析数据获取经纬度信息 4、存储数据 三、代码实现 四、注意事项和优化建议 五、充电桩数据的后续利用 六、总结 一、引言 随着电动汽车的普及,充电设施的建设也日…

【JavaEESpring】Spring Web MVC⼊⻔

Spring Web MVC 1. 什么是 Spring Web MVC1.1 什么是 MVC ?1.2 是什么 Spring MVC? 2. 学习 Spring MVC2.1 建立连接2.2 请求2.3 响应 3. 相关代码链接 1. 什么是 Spring Web MVC 官⽅对于 Spring MVC 的描述是这样的: 1.1 什么是 MVC ? MVC 是 Model View C…

OpenCV实现手势虚拟拖拽

前言: Hello大家好,我是Dream。 今天来学习一下如何使用OpenCV实现手势虚拟拖拽,欢迎大家一起前来探讨学习~ 一、主要步骤及库的功能介绍 1.主要步骤 要实现本次实验,主要步骤如下: 导入OpenCV库。通过OpenCV读取摄…

中文编程软件视频推荐,自学编程电脑推荐,中文编程开发语言工具下载

中文编程软件视频推荐,自学编程电脑推荐,中文编程开发语言工具下载 给大家分享一款中文编程工具,零基础轻松学编程,不需英语基础,编程工具可下载。 这款工具不但可以连接部分硬件,而且可以开发大型的软件…

使用create-react-app脚手架创建react项目

查看npx版本: npx -v使用如下命令创建项目时: npx create-react-app demo报错: 解决: 以管理员身份运行cmd 然后再次创建项目,又报错: 经查得知:发生此错误是因为用户名中有空格,…

商城免费搭建之java商城 开源java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c

1. 涉及平台 平台管理、商家端(PC端、手机端)、买家平台(H5/公众号、小程序、APP端(IOS/Android)、微服务平台(业务服务) 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

IPv6详解

目录: 第一部分 IPv6的诞生背景和引起的主要变化 第二部分 IPv6数据报的基本首部和扩展首部 第三部分 IPv6地址 第四部分 IPv4向IPv6过渡 第一部分 IPv6的诞生背景和引起的主要变化 一.IPv6的诞生背景 IPv4存在设计缺陷: IPv4的设计者最初并没有想到该协议会在全球范围内广…

NFS文件系统共享服务器实战

架设一台NFS服务器,并按照以下要求配置 准备 两台Linux虚拟机一台作为服务端server,一台作为客户端client server IPV4:192.168.110.136/24 client IPV4:192.168.110.134/24 两台服务器都需要关闭防火墙和seLinux 服…

element-ui中el-table数据合并行和列,应该怎么解决

最近接到一个任务,要实现一个数据报表,涉及到很多合并问题,一开始想着原生会简单点,实际上很麻烦,最后还是用elemen-ui中table自带的合并方法. 最终的效果是要做成这种:1.数据处理,后端返回来的数据是,一个大对象,包含三个数组,既然合并,肯定是要处理成一个数组,并且要把相同的…

Zabbix之部署代理服务器

一、部署代理服务器 分布式监控的作用 分担server的几种式压力解决多机房之间的网络延时问题 1、搭建proxy主机 1.1 关闭防火墙,修改主机名 systemctl disbale --now firewalld setenforce 0 hostnamectl set-hostname zbx-proxy su1.2 设置zabbix下载源 rpm …

FreeRTOS源码阅读笔记2--list.c

list.c中主要完成列表数据结构的操作,有列表和列表项的初始化、列表的插入和移除。 2.1列表初始化vListInitialise() 2.1.1函数原型 void vListInitialise( List_t * const pxList ) pxList:列表指针,指向要初始化的列表。 2.1.2函数框架…

执行mysql-community-libs-8.1.0-1.el8.x86_64.rpm报错依赖检测失败

目录 1.错误信息 2.解决方法 1.错误信息 我是在VMware虚拟机18上的Centos8上的,安装MySQL8.1.0,执行mysql-community-libs-8.1.0-1.el8.x86_64.rpm报错 [rootlocalhost mysql8.1.0]# rpm -ivh mysql-community-libs-8.1.0-1.el8.x86_64.rpm 警告&…

SpringBoot前后端分离整合cas(客户端)

SpringBoot前后端分离整合cas&#xff08;客户端&#xff09; cas认证详细流程&#xff1a; 前后端分离&#xff1a;项目前端使用nginx启动&#xff0c;后端是springBoot服务&#xff1b; nginx可以统一管理Cookie&#xff0c;避免出现跨域问题。 添加依赖 <dependency&g…

C语言常见面经详细总结

1、递归函数定义没有问题&#xff0c;递归深层次后易引发什么问题&#xff1f; &#xff08;1&#xff09;影响执行效率 &#xff08;2&#xff09;栈溢出。 因为每一次调用函数是&#xff0c;栈区都要给函数分配空间&#xff0c;而且上一次调用并没有结束&#xff0c;调用的…

挑战100天 AI In LeetCode Day07(热题+面试经典150题)

挑战100天 AI In LeetCode Day07&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-92.1 题目2.2 题解 三、面试经典 150 题-93.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&am…

2023年下半年架构案例真题及答案

案例的考点&#xff1a; 大数据架构 Lambda架构和Kappa架构 jwt特点 数据持久层&#xff0c;Redis数据丢失&#xff0c;数据库读写分离方案 Hibernat架构 SysML七个关系&#xff0c;填需求图 大数据的必选题&#xff1a; 某网作为某电视台在互联网上的大型门户入口&#…

Python高级语法----深入理解Python协程

文章目录 什么是协程?Python中的协程基本示例协程和事件循环总结Python协程是一种非常强大的并发编程概念,让你能够高效地处理多任务。协程在Python中的使用已经变得越来越流行,特别是在异步编程中。本文将用通俗易懂的语言来介绍协程的概念,并提供实际的代码示例和执行结果…