RESTful API 为何成为顶流 API 架构风格?

news2024/11/26 18:21:05

作者孙毅,API7.ai 技术工程师,Apache APISIX Committer

万物互联的世界充满着各式各样的 API ,如何统筹规范 API 至关重要。RESTful API 是目前世界上最流行的 API 架构风格之一,它可以帮助你实现客户端与服务端关注点分离,让前后端各自迭代,提升管理效率;其无状态的特性可以让应用更容易扩展,更容易的实现缓存策略从而提升系统性能和用户体验。本文将介绍什么是 RESTful API 以及我们如何使用它。

首先,抛开 API 这个概念,我们来聊聊在生活中如何传递信息。

当你在商店将钱拿给老板告诉他你需要买电池,老板在收到钱后在货架上找到电池并递给你。一个买电池的交易顺利完成。

计算机软件则通过 API 来完成信息的传递,先来看维基百科定义:

An application programming interface (API) is a way for two or more computer programs to communicate with each other. It is a type of software interface, offering a service to other pieces of software.

软件 A 通过 API 向软件 B 发起请求,软件 B 在查询自己资源后将请求的响应内容通过 API 返回 A。

软件 A 通过 API 向软件 B 发起请求就好比你跟老板说你需要电池,软件 B 在将数据返回给软件 A 就好比老板找到电池后将电池给你。

这一过程软件 B 不需要知道软件 A 为什么要数据,就好比商店老板不会问你买电池的目的。软件 A 也不需要知道 B 软件的数据是怎么找到的,就好比你买电池的时候你也不会问老板电池从哪里进货一样。每个软件之间通过 API 传递信息,各司其事,使得程序世界变得有序可靠。

什么是 RESTful API

Roy Fielding 在他 2000 年的博士论文《建筑风格和基于网络的软件架构设计》中定义了REST(Representational state transfer),REST 架构风格定义了六个指导性约束。一个符合部分全部约束的系统被松散地称为 RESTful。

RESTful API (图片来源:Seobility)

REST 的约束条件(长龙在排版时可以考虑一键截图 or 分点>横向叙述)

约束条件详述优势
Client–server architecture通过将用户界面问题与数据存储问题分开,提高了跨多个平台的用户界面的可移植性,并通过简化服务器组件提高了可扩展性。1. 客户端、服务端解耦。
2. 提升用户平台跨平台的可移植性。
3. 提升服务器端的可拓展性。
Statelessness客户端的每个请求到服务器必须包含请求所需的所有信息,并且不能利用服务器上存储的任何上下文,会话状态完全保存在客户端。1. 易扩展,无会话依赖,任何服务器可以处理任何请求。
2. 易缓存,提升程序性能。
Cacheability要求请求响应中的数据被隐式或显式标记为可缓存或不可缓存。如果一个响应是可缓存的,那么客户端缓存就被授予为以后的等效请求重用该响应数据的权利。1. 减少带宽。
2. 减少延迟。
3. 减少服务器负载。
4. 隐藏网络状态。
Layered system通过约束组件行为允许架构由分层层组成,这样每个组件都不能“看到”超出它们与之交互的直接层。通过将系统知识限制在单个层,降低了整个系统的复杂性并促进了底层独立性。1. 降低整个系统的复杂性。
2. 促进底层的独立性。
3. 可方便的实施负载均衡。
4. 可将业务逻辑和安全策略解耦。
Code on demand (optional)允许通过下载和执行小程序或脚本形式的代码来扩展客户端功能。1. 提高系统的可扩展性。
Uniform interface主要包含四点:
1. Resource identification in requests.
客户能够通过请求中包含的 URI 来识别一个资源,将服务端资源和客户端请求资源解耦。
2. Resource manipulation through representations.
当客户端拥有一个资源的表示,如 URI,那么就有足够的信息来修改或者删除资源。
3. Self-descriptive messages.
每个消息都包括足够的信息来告知客户客户端该如何处理该信息。
4. Hypermedia as the engine of application state (HATEOAS).
客户端不需要任何额外的编码通过服务端返回的资源链接,就可以使得用户获取所有的资源。
1. 简化了整体系统架构。
2. 提高了交互的可见性。

RESTful API 最佳实践

强调组件间的 统一接口 是 REST 架构风格与其他基于网络的风格区分开来的核心特征,基于此特征,本文梳理了RSETful 最佳实践,以帮助你更好的设计 API。

路径名称避免动词

使用 HTTP 方法来表达资源操作行为,而不是将行为动词定义到路径中。

// Good
curl -X GET http://httpbin.org/orders

// Bad
curl -X GET "http://httpbin.org/getOrders"
  • GET 获取指定 URI 的资源信息
// 代表获取当前系统的所有订单信息
curl -X GET http://httpbin.org/orders

// 代表获取订单编号为 1 的订单详情信息
curl -X GET http://httpbin.org/orders/1
  • POST 通过指定的 URI 创建资源
 // 代表创建一个名称为 order 的资源
curl -X POST http://httpbin.org/orders \
  -d '{"name": "awesome", region: "A"}' \
  • PUT 创建或全量替换指定 URI 上的资源
 // 代表将 id 为 1 的 order 进行数据替换
curl -X PUT http://httpbin.org/orders/1 \
  -d '{"name": "new awesome", region: "B"}' \
  • PATCH 执行一个资源的部分更新
 // 代表将 id 为 1 的 order 中的 region 字段进行更改,其他数据保持不变
curl -X PATCH http://httpbin.org/orders/1 \
  -d '{region: "B"}' \
  • DELETE 通过指定的 URI 移除资源
 // 代表将 id 为 1 的 order 删除
curl -X DELETE http://httpbin.org/orders/1

URI 使用复数形式

若使用单数的形式来表示获取某一类资源,例如:

curl -X GET "http://httpbin.org/order"

使用单数形式,会使用户产生该系统中只有一个 order 的困惑,用复数形式在逻辑上则顺畅很多。

curl -X GET "http://httpbin.org/orders"

善用 HTTP 状态码

HTTP 标准定义个状态码,大致可以分为以下几类:

状态码含义
2xx成功,操作被成功接收并处理
3xx重定向,需要进一步的操作以完成请求
4xx客户端错误,请求包含语法错误或无法完成请求
5xx服务器错误,服务器在处理请求的过程中发生了错误

使用标准状态码,开发人员可以立即识别问题,可以减少发现不同类型错误的时间。

版本管理

随着业务需求的变更,已经上线的 API 大概率是要对应调整的。如果我们的 API 有第三方在使用,让每一个客户端根据我们 API 的变更而变更显然是不可能的,这个时候就要引入 API 版本管理概念了,既可以保证历史 API 正常使用,又可以迭代新的 API 以满足新的业务需求。

常见的版本控制手段有:

  • 通过请求中路径来做版本控制
// 请求 v1 版本的API
curl  http://httpbin.org/v1/orders

// 请求 v2 版本的API
curl  http://httpbin.org/v2/orders
  • 通过 Query 参数来做版本控制
// 请求 v1 版本的API
curl  http://httpbin.org/orders?version=v1

// 请求 v2 版本的API
curl  http://httpbin.org/v2/orders?version=v2
  • 通过 Header 来做版本控制
// 请求 v1 版本的API
curl  http://httpbin.org/orders -H "custom-version: v1"

// 请求 v2 版本的API
curl  http://httpbin.org/orders -H "custom-version: v2"

APISIX 如何助力 RESTful API

作为一个动态、实时、高性能的 API 网关,Apache APISIX 可以在任何 RESTful API 服务上运行,并使用插件来添加新的服务和扩展其功能,这符合 RESTful 定义中的 Layered system。此外,对于一些没有遵循 RESTful API 定义的历史服务, APISIX 也可以帮你在不改动原有业务代码的情况下完成接口的转换,使你的接口完成 Uniform interface 这一 REST 限制条件,使你的 API 可以更好的遵守 RESTful API 规范。

分层系统:支持业务逻辑和安全逻辑的分割

你可以只用关注业务逻辑的实现,接口的安全逻辑可以交给 APISIX Authentication 类插件处理,例如 key-auth。APISIX 支持大量的 Authentication 插件,我们以 openid-connet为例如下图所示:

APISIX的作用

我们可以看到,使用 APISIX(API Gateway)在业务服务器前面加一层认证逻辑,就可以起到保护上游服务的作用,让你的业务逻辑和安全逻辑高效解耦。

Layered system:多负载均衡协议支持

APISIX 作为 API 网关,可以设立在客户端和服务端之间,完成不同的负载需求。你甚至可以自定义负载均衡的逻辑。

支持的负载均衡算法有:

  • roundrobin: Round robin balancing with weights.
  • chash: Consistent hash.
  • ewma: Pick the node with minimum latency. See EWMA Chart for more details.
  • least_conn: Picks the node with the lowest value of (active_conn + 1) / weight. Here, an active connection is a connection being used by the request and is similar to the concept in Nginx.
  • user-defined load balancer loaded via require("apisix.balancer.your_balancer")

统一接口:使历史 API 更加 RESTful

对于已经存在很久的历史 API,如果没有很好的遵循 RESTful API 准则。你可以在不改造原有 API 逻辑的情况下重新通过 APISIX 来封装新的 API 以满足不同的业务场景。

使用 proxy-rewrite 改写客户端请求

在本文中上方提过我们的路径中不要有动词。

例如:历史版本 API 有 /getOrder 接口,我们可以通过 proxy-rewrite 插件来将 API 请求代理到历史 API 上:

curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "methods": ["GET"],
    "uri": "/orders",
    "plugins": {
        "proxy-rewrite": {
            "uri": "/getOrder",
            "scheme": "http",
        }
    },
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:80": 1
        }
    }
}'

你也可以同样使用该插件进行 API 版本管理上的操作。

使用 response-rewrite 插件改写服务端响应

当我们的历史 API 存在响应状态码不规范时,我们可以通过 response-rewrite 代理 response 响应从而达到修改响应状态码的目的。

curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "methods": ["GET"],
    "uri": "/orders",
    "plugins": {
        "response-rewrite": {
            "status_code": 201,
            "body": "{\"code\":\"ok\",\"message\":\"new json body\"}",
            "vars":[
                [ "status","==",200 ]
            ]
        }
    },
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:80": 1
        }
    }
}'

例如,这个例子表示将请求 /orders 路径的 API 中响应为 200 的状态的请求修改为 201。 APISIX 支持非常丰富的插件,期待你去挖掘更多的玩法。

总结

本文详细说明了什么是 API,什么是 RESTful API 以及其最佳实践。另外还介绍了如何通过 APISIX 来实现业务逻辑和安全逻辑分离,如何使用 APISIX 在不改动原有业务代码的情况下将历史 API 服务更加 RESTful。希望本文对你了解 RESTful API 有所帮助,也欢迎你来 GitHub 一起玩耍。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3 企业级优雅实战 - 组件库框架 - 12 发布开源组件库

前面使用了 11 篇文章分享基于 vue3 、Monorepo 的组件库工程完整四件套(组件库、文档、example、cli)的开发、构建及组件库的发布。本文属于这 11 篇文章的扩展 —— 如何发布到 GitHub 上以及如何快速利用 GitHub 发布组件库文档。这样优雅哥的《组件库…

Springboot862大学生社团管理系统

后台两大功能模块, (1)管理员:个人中心、学校管理、学院管理、年级管理、班级管理、社长管理、学生管理、社团类型管理、社团信息管理、社团成员管理、退团记录管理、社团活动管理、活动报名管理、退出活动管理、社团事务管理、系统管理。 (2)社长&#…

PyTorch学习笔记:nn.SmoothL1Loss——平滑L1损失

PyTorch学习笔记:nn.SmoothL1Loss——平滑L1损失 torch.nn.SmoothL1Loss(size_averageNone, reduceNone, reductionmean, beta1.0)功能:创建一个平滑后的L1L_1L1​损失函数,即Smooth L1: l(x,y)L{l1,…,lN}Tl(x,y)L\{l_1,\dots,l…

【Python爬虫实战案例】采集城市桌游商家数据信息,做可视化演示

前言 这里容我罗嗦几句 😗 这个时间,我想大学生应该都回学校了吧,嘿嘿 现在应该蛮忙的,有些的还要准备开学考,临近毕业的朋友,也快要因为工作而烦恼了,但是!! 咱也是…

新版国家标准GB/T 28181—2022将于2023年7月1日正式实施,与GB/T 28181—2016差别有哪些?

新版国家标准GB/T28181-2022《公共安全视频监控联网系统信息传输、交换、控制技术要求》已于2022年12月30日发布,将于2023年7月1日正式实施。与GB/T 28181—2016相比,除结构调整和编辑性改动外,主要技术变化如下。——更改了标准范围&#xf…

排序:堆排序

一、树与二叉树 二、二叉树 1.二叉树:度不超过2的树(度:树的分支),每个节点最多有两个孩子节点,两个孩子节点被区分为左孩子节点和右孩子节点。 2.满二叉树:一个二叉树,如果每一个层…

minio查询桶中文件,桶目录中文件

文章目录前言一、文件桶中的文件夹是什么?二、文件查询1.桶中文件查询2.桶中文件夹中的文件查询总结前言 文章再续,书接上文 minio进阶分页查询 说到了文件,可以实现分页查询,然后上次查询的是桶中的文件列表,这次遇到了需要数据隔离的文件,也就是需要在桶中再次建…

I.MX6ULL内核开发3:linux内核设计字符设备原理(简单版)

目录 一、Linux哲学 二、如何把字符设备抽象成文件 三、硬件层原理 四、驱动层原理 五、文件系统原理 一、Linux哲学 一切皆文件 二、如何把字符设备抽象成文件 open函数,在文件系统中找到指定文件的操作接口,绑定到进程task_struct->file_str…

2023-02-10 - 4 丰富的搜索功能

ES为用户提供了丰富的搜索功能:既有基本的搜索功能,又有搜索建议功能;既有常用的普通类型的匹配功能,又有基于地理位置的搜索功能;既提供了分页搜索功能,又提供了搜索的调试分析功能。 1 搜索辅助功能 俗…

人大金仓数据库的归档日志

归档日志 归档日志是非活动的WAL日志备份。通过使用归档日志,可以保留所有WAL日志的历史记录,当数据库处于ARCHIVELOG模式并进行日志切换时,后台进程archiver process会将WAL日志的内容保存到归档日志中,当数据库出现介质失败时&…

2017-PMLR-Neural Message Passing for Quantum Chemistry

2017-PMLR-Neural Message Passing for Quantum Chemistry Paper: https://arxiv.org/pdf/1704.01212.pdf Code: https://github.com/brain-research/mpnn 量子化学的神经信息传递 这篇文献作者主要是总结了先前神经网络模型的共性,提出了一种消息传递神经网络&am…

掌握了这项技能的性能测试师,90%都升职加薪了

初入职场的新人该怎么做才能让自己快速成长?在公司一直做着手工测试,如何才能提升自己,避免陷入“只涨年龄不涨经验”的尴尬?做为一名软件测试工程师,我们不得不去面对这些问题,有的人找到了答案&#xff0…

你不会还不知道如何监测用户的网络是否在线吧?

我最近遇到一个需求,要给网站添加一个用户网络离线提醒。要求我们要实时监测用户的网络状态,当用户断网了,我们要立马给用户弹出一个断网提醒。 那你可能会问,为什么要做这么一个需求呢?用户断网了,网页不…

华为、南卡和漫步者蓝牙耳机怎么选?国产高性价比蓝牙耳机推荐

随着蓝牙耳机的快速发展,现如今使用蓝牙耳机的人也越来越多。其中,日益增多的国产蓝牙耳机品牌也逐渐被大众认识、认可。目前一些热销的国产蓝牙耳机,如华为、南卡和漫步者等都是大家比较熟知的品牌。那么,这三个品牌哪个性价比高…

已解决SqlServer报错Arithmetic overflow error converting expression to data type int

本文记录(pymssql.OperationalError) (8115, b’Arithmetic overflow error converting expression to data type int.DB-Lib error message 20018, severity 16:\nGeneral SQL Server error: Check messages from the SQL Server\n’)报错解决方法,亲测有效&#x…

教师教学短视频录制有好用工具分享:

别再为制作微课发愁了啦,掌握这7款微课制作神器软件,让你的工作效率超级加倍! 话不多说,一起来看看有哪些宝藏软件吧~ canvas 平台:电脑、网页、手机 定位:超多模板的制图软件 制作PPT、手抄报、奖状都…

手把手带你体验ChatGPT

1、ChatGPT介绍 ChatGPT,美国OpenAI 研发的聊天机器人程序 ,于2022年11月30日发布 。ChatGPT是人工智能技术驱动的自然语言处理工具,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,真正像人…

修复 KubeSphere 内置 Jenkins 的 Apache Log4j2 漏洞

作者:老Z,中电信数智科技有限公司山东分公司运维架构师,云原生爱好者,目前专注于云原生运维,云原生领域技术栈涉及 Kubernetes、KubeSphere、DevOps、OpenStack、Ansible 等。 简介 生产环境 KubeSphere 3.3.0 部署的…

【网络~】

网络一级目录二、socket套接字三、UDP数据报套接字四、TCP流套接字一级目录 1.局域网、广域网 2.IP地址是什么? IP地址是标识主机在网络上的地址 IP地址是如何组成的? 点分十进制,将32位分为四个部分,每个部分一个字节&#xff…

He3 更新:中文

系统级更新 焕然一新的主界面 这一次对整体 UI 界面做了一个大的调整,整体更加扁平美观,布局更加紧凑协调,视觉层面更加集中聚焦。 旧版 新版 工具内容居中 上下文工具以及关联工具放置在右侧,工具内容居中,在使…