统一 REST 接口规范:提升低代码平台研发效率

1.背景

在一个低代码研发团队的办公室里,大家正忙碌着。小张在调试组件,小李在优化性能,小王则在制定新项目的技术方案。

这时,团队负责人小刘走进来,对大家说:“我们需要聊聊 REST 接口规范的问题。”他指出,最近团队在集成过程中遇到了很多接口不规范的问题,导致开发效率下降和频繁的错误。

小李点头说:“不同团队对接口的理解不同,导致组件兼容性问题。”小王也表示:“有时候我们甚至不知道接口会返回什么样的数据结构。”

小刘继续说:“为了提高效率和稳定性,我们需要统一 REST 接口的规范,这不仅有助于我们的合作,也有助于平台的扩展和维护。”

大家纷纷表示赞同。于是,他们决定今天的会议讨论 REST 接口规范的最佳实践,以及如何在低代码平台中实施和推广。

通过这样的交流,团队意识到制定统一的 REST 接口规范的重要性。

接下来,本文将详细介绍这些规范,并探讨如何在低代码平台中实现,以提升开发效率和系统稳定性。

2.RESTful API 介绍

在回答“RESTful API 是什么”之前,我们先来看下 REST 是什么意思:REST 代表的是表现层状态转移(REpresentational State Transfer),由 Roy Fielding 在他的论文《Architectural Styles and the Design of Network-based Software Architectures》里提出。REST 本身并没有创造新的技术、组件或服务,它只是一种软件架构风格,是一组架构约束条件和原则,而不是技术框架。

REST 有一系列规范,满足这些规范的 API 均可称为 RESTful API。REST 规范把所有内容都视为资源,也就是说网络上一切皆资源。REST 架构对资源的操作包括获取、创建、修改和删除,这些操作正好对应 HTTP 协议提供的 GET、POST、PUT 和 DELETE 方法。

REST 风格虽然适用于很多传输协议,但在实际开发中,由于 REST 天生和 HTTP 协议相辅相成,因此 HTTP 协议已经成了实现 RESTful API 事实上的标准。所以,REST 具有以下核心特点:

1.以资源(resource)为中心,所有的东西都抽象成资源,所有的行为都应该是在资源上的 CRUD 操作。

  • 资源对应着面向对象范式里的对象,面向对象范式以对象为中心。
  • 资源使用 URI 标识,每个资源实例都有一个唯一的 URI 标识。例如,如果我们有一个用户,用户名是 admin,那么它的 URI 标识就可以是 /users/admin。

2.资源是有状态的,使用 JSON/XML 等在 HTTP Body 里表征资源的状态。

3.客户端通过四个 HTTP 动词,对服务器端资源进行操作,实现“表现层状态转化”。

4.无状态,这里的无状态是指每个 RESTful API 请求都包含了所有足够完成本次操作的信息,服务器端无须保持 session。无状态对于服务端的弹性扩容是很重要的。

提示:因为怕你弄混概念,这里强调下 REST 和 RESTful API 的区别:REST 是一种规范,而 RESTful API 则是满足这种规范的 API 接口。

3.RESTful API 设计原则

上面我们说了,RESTful API 就是满足 REST 规范的 API,由此看来,RESTful API 的核心是规范,那么具体有哪些规范呢?

接下来从 URI 设计、API 版本管理等七个方面,详细介绍 RESTful API 的设计原则。

3.1.URI 设计

资源都是使用 URI 标识的,我们应该按照一定的规范来设计 URI,通过规范化可以使我们的 API 接口更加易读、易用。

以下是 URI 设计时,应该遵循的一些规范:

1.资源名使用名词而不是动词,并且用名词复数表示。资源分为 Collection 和 Member 两种。

  • Collection:一堆资源的集合。例如我们系统里有很多用户(User),这些用户的集合就是 Collection。Collection 的 URI 标识应该是 域名/资源名复数, 例如 example.com/v1/users。
  • Member:单个特定资源。例如系统中特定名字的用户,就是 Collection 里的一个 Member。Member 的 URI 标识应该是 域名/资源名复数/资源名称, 例如 example.com/v1/users/colin。

2.URI 结尾不应包含 / 。

3.URI 中不能出现下划线 _,必须用中杠线 - 代替(有些人推荐用 _,有些人推荐用 -,统一使用一种格式即可,我比较推荐用 -)。

4.URI 路径用小写,不要用大写。

5.避免层级过深的 URI。超过 2 层的资源嵌套会很乱,建议将其他资源转化为 ? 参数,比如

/schools/qinghua/classes/rooma/students/colin # 不推荐
/students?school=qinghua&class=rooma # 推荐

这里有个地方需要注意:在实际的 API 开发中,可能你会发现有些操作不能很好地映射为一个 REST 资源。

这时候,你可以参考下面的做法。

  • 将一个操作变成资源的一个属性,比如想在系统中暂时禁用某个用户,可以这么设计 URI:/users/colin?active=false。
  • 将操作当作是一个资源的嵌套资源,比如一个 GitHub 的加星操作:
PUT /gists/:id/star # github star action
DELETE /gists/:id/star # github unstar action

如果以上都不能解决问题,有时可以打破这类规范。比如登录操作,登录不属于任何一个资源,URI 可以设计为:/v1/login。

在设计 URI 时,如果你遇到一些不确定的地方,推荐你参考 GitHub 标准 RESTful API

3.2.REST 资源操作映射为 HTTP 方法

基本上 RESTful API 都是使用 HTTP 协议原生的 GET、PUT、POST、DELETE 来标识对资源的 CRUD 操作,形成的规范如下表所示:

HTTP 方法

Collection资源 (/users)

Member资源 (/users/{id})

GET

获取一个 Collection 下所有的 Member 信息

获取一个 Member 的状态表征

POST

在 Collection 中新建一个 Member

-

PUT

用另外一个 Collection 替换这个 Collection

更新一个 Member 的状态表征

DELETE

删除整个 Collection,可以用来批量删除资源

删除这个 Member

提示:Collection 代表资源集合,Member 代表特定的资源。

下面是一个具体的映射例子:

HTTP 方法

行为

URL

示例说明

GET

获取资源列表

/users

获取一个 Member 的状态表征

GET

获取一个具体的资源表述

/users/{id}

获取ID用户的详细信息

POST

创建一个新的资源

/users

创建一个新的用户

PUT

更新一个资源

/users/{id}

更新用户ID为{id}的用户

DELETE

删除服务器上的一个资源

/users/{id}

删除用户ID为{id}的用户

GET、PUT、POST、DELETE 是 RESTful API 最常用的 HTTP 请求方法。HTTP 还提供了另外 3 种请求方法,这些方法不经常使用,这里也列举出来供你参考:

HTTP 方法

Collection资源 (/users)

Member资源 (/users/{id})

PATCH

整个 Collection 进行部分更新,通常用于更新 Collection 的某些属性或字段

获取一个 Member 的元信息

HEAD

获取一个 Collection 的元信息,但不需要获取实际资源的内容

获取 Member 的元信息,但不需要获取实际资源的内容

OPTIONS

获取整个 Collection 支持的通信选项,比如支持的 HTTP 方法、请求头等信息

获取 Member 支持的通信选项,包括支持的 HTTP 方法、请求头等信息

提示:OPTIONS 请求方法通常用于跨域请求时的预检请求。

对资源的操作应该满足安全性和幂等性:

  • 安全性:不会改变资源状态,可以理解为只读的。
  • 幂等性:执行 1 次和执行 N 次,对资源状态改变的效果是等价的。

使用不同 HTTP 方法时,资源操作的安全性和幂等性对照见下表:

HTTP 方法

是否安全

是否幂等

GET

POST

PUT

DELETE

PATCH

HEAD

OPTIONS

在使用 HTTP 方法的时候,有以下两点需要你注意:

  • GET 返回的结果,要尽量可用于 PUT、POST 操作中。例如,用 GET 方法获得了一个 user 的信息,调用者修改 user 的邮件,然后将此结果再用 PUT 方法更新。这要求 GET、PUT、POST 操作的资源属性类型是一样的。
  • 如果对资源进行状态/属性变更,要用 PUT 方法,POST 方法仅用来创建或者批量删除这两种场景。

在设计 API 时,经常会有批量删除的需求,需要在请求中携带多个需要删除的资源名,但是 HTTP 的 DELETE 方法不能携带多个资源名,这时候可以通过下面三种方式来解决:

  • 发起多个 DELETE 请求。
  • 操作路径中带多个 id,id 之间用分隔符分隔, 例如:DELETE /v1/users?ids=1,2,3 。
  • 直接使用 POST 方式来批量删除,Body 中传入需要删除的资源列表。

其中,第二种是我最推荐的方式,因为使用了匹配的 DELETE 动词,并且不需要发送多次 DELETE 请求。这时候,你可能会问如果 id 列表太长,会不会有性能问题?其实不会的,因为在一个真实的项目中,我们每次允许删除的条目个数是有限的,每次最大删除的条目数,通常跟每个页面的最大展示条数保持一致。

你需要注意的是,这三种方式都有各自的使用场景,你可以根据需要自行选择。如果选择了某一种方式,那么整个项目都需要统一用这种方式。

3.3.匹配 HTTP 请求方法的参数

HTTP 有很多请求方法,例如:GET、PUT、POST、DELETE 等。在执行 HTTP 请求时,根据请求方法的类型,其参数指定位置也是有规范。在执行请求时,HTTP 请求方法和请求参数不匹配的请求,客户端会报错或者拒绝请求。

HTTP 请求参数,可以视情况设置在以下位置:

  • 查询参数(Query Parameters):查询参数是附加在 URL 路径后面的键值对,使用 ? 开头,多个参数之间使用 & 分隔,例如:http://example.com/api/resource?param1=value1&param2=value2。查询参数通常用于对资源进行过滤、分页、排序等操作;
  • 路径参数(Path Parameters):路径参数是出现在 URL 路径中的一部分,通常用花括号 {} 包裹,例如:http://example.com/api/resource/{id}。路径参数用于标识资源的唯一标识符或者其他需要在 URL 中直接体现的参数;
  • 请求头(Request Headers):请求头是包含在 HTTP 请求头部中的键值对,例如:Content-Type: application/json。请求头用于传递请求的元数据、授权信息、内容类型等;
  • 请求体(Request Body):请求体是包含在 HTTP 请求中的主体部分,通常用于 POST、PUT、PATCH 等方法中传递数据。请求体用于传递请求的具体数据,通常使用 JSON、XML 等格式;
  • Cookie:Cookie 是存储在客户端的一小段文本信息,会随着每次请求被发送到服务器。Cookie 用于在客户端和服务器之间保持状态,通常用于会话管理、用户认证等。

下表是不同 HTTP 请求方法所支持的请求参数的设置位置:

HTTP 方法

参数位置

GET

适配的请求参数位置:查询参数(Query Parameters)和路径参数(Path Parameters);GET 请求通常通过查询参数传递参数,也可以通过路径参数传递需要标识的资源。

POST

适配的请求参数位置:请求体(Request Body);POST 请求通常通过请求体传递需要创建的资源的数据。

PUT

适配的请求参数位置:路径参数(Path Parameters)和请求体(Request Body);PUT 请求通常通过路径参数指定要更新的资源,通过请求体传递更新后的数据。

DELETE

适配的请求参数位置:路径参数(Path Parameters);DELETE 请求通常通过路径参数指定要删除的资源。

PATCH

适配的请求参数位置:路径参数(Path Parameters)和请求体(Request Body);PATCH 请求通常通过路径参数指定要部分更新的资源,通过请求体传递更新的部分数据。

HEAD

适配的请求参数位置:查询参数(Query Parameters)和路径参数(Path Parameters);HEAD 请求通常通过查询参数和路径参数传递参数,用于获取资源的元信息而不获取资源本身。

OPTIONS

适配的请求参数位置:无特定参数位置要求;OPTIONS 请求通常用于获取目标资源所支持的通信选项,不需要特定的请求参数位置。

​​​​​​​3.4.统一的返回格式

一般来说,一个系统的 RESTful API 会向外界开放多个资源的接口,每个接口的返回格式要保持一致。另外,每个接口都会返回成功和失败两种消息,这两种消息的格式也要保持一致。不然,客户端代码要适配不同接口的返回格式,每个返回格式又要适配成功和失败两种消息格式,会大大增加用户的学习和使用成本。返回的格式没有强制的标准,你可以根据实际的业务需要返回不同的格式。

​​​​​​​​​​​​​​3.5.API 版本管理

随着时间的推移、需求的变更,一个 API 往往满足不了现有的需求,这时候就需要对 API 进行修改。对 API 进行修改时,不能影响其他调用系统的正常使用,这就要求 API 变更做到向下兼容,也就是新老版本共存。

但在实际场景中,很可能会出现同一个 API 无法向下兼容的情况。这时候最好的解决办法是从一开始就引入 API 版本机制,当不能向下兼容时,就引入一个新的版本,老的版本则保留原样。这样既能保证服务的可用性和安全性,同时也能满足新需求。

API 版本有不同的标识方法,在 RESTful API 开发中,通常将版本标识放在如下 3 个位置:

  • URL 中,比如 /v1/users。
  • HTTP Header 中,比如 Accept: vnd.example-com.foo+json; version=1.0。
  • Form 参数中,比如 /users?version=v1。

通常建议将版本标识放在 URL 中的,比如 /v1/users,这样做的好处是很直观,GitHub、Kubernetes、Etcd 等很多优秀的 API 均采用这种方式。

这里要注意,有些开发人员不建议将版本放在 URL 中,因为他们觉得不同的版本可以理解成同一种资源的不同表现形式,所以应该采用同一个 URI。对于这一点,没有严格的标准,根据项目实际需要选择一种方式即可。

​​​​​​​3.6.API 命名

API 通常的命名方式有三种,分别是驼峰命名法(serverAddress)蛇形命名法(server_address)脊柱命名法(server-address)

驼峰命名法和蛇形命名法都需要切换输入法,会增加操作的复杂性,也容易出错,所以这里建议用脊柱命名法。GitHub API 用的就是脊柱命名法,例如 selected-actions。

​​​​​​​3.7.统一分页/过滤/排序/搜索功能

REST 资源的查询接口,通常情况下都需要实现分页、过滤、排序、搜索功能,因为这些功能是每个 REST 资源都能用到的,所以可以实现为一个公共的 API 组件。下面来介绍下这些功能。

  • 分页:在列出一个 Collection 下所有的 Member 时,应该提供分页功能,例如 /users?offset=0&limit=20(limit,指定返回记录的数量;offset,指定返回记录的开始位置)。引入分页功能可以减少 API 响应的延时,同时可以避免返回太多条目,导致服务器/客户端响应特别慢,甚至导致服务器/客户端 crash 的情况。
  • 过滤:如果用户不需要一个资源的全部状态属性,可以在 URI 参数里指定返回哪些属性,例如 /users?fields=email,username,address。
  • 排序:用户很多时候会根据创建时间或者其他因素,列出一个 Collection 中前 100 个 Member,这时可以在 URI 参数中指明排序参数,例如 /users?sort=age,desc。
  • 搜索:当一个资源的 Member 太多时,用户可能想通过搜索,快速找到所需要的 Member,或着想搜下有没有名字为 xxx 的某类资源,这时候就需要提供搜索功能。搜索建议按模糊匹配来搜索。

4.总结

本文详细介绍了 RESTful API 及 RESTful API 设计原则。REST 是一种 API 规范,而 RESTful API 则是满足这种规范的 API 接口,RESTful API 的核心是规范。

在 REST 规范中,资源通过 URI 来标识,资源名使用名词而不是动词,并且用名词复数表示,资源都是分为 Collection 和 Member 两种。RESTful API 中,分别使用 POST 、 DELETE 、 PUT 、 GET 来表示 REST 资源的增删改查,HTTP 方法、Collection、Member 不同组合会产生不同的操作,具体的映射你可以看下 REST 资源操作映射为 HTTP 方法 部分的表格。

为了方便用户使用和理解,每个 RESTful API 的返回格式、错误和正确消息的返回格式,都应该保持一致。RESTful API 需要支持 API 版本,并且版本应该能够向前兼容,我们可以将版本号放在 URL 中、HTTP Header 中、Form 参数中,但这里我建议将版本号放在 URL 中,例如 /v1/users,这种形式比较直观。

另外,我们可以通过脊柱命名法来命名 API 接口名。对于一个 REST 资源,其查询接口还应该支持分页/过滤/排序/搜索功能,这些功能可以用同一套机制来实现。

参考资料

GitHub REST API documentation - GitHub Docs

Architectural Styles and the Design of Network-based Software Architectures

作者介绍:

道一云七巧低代码开发平台,让零代码人员也能轻松构建企业级应用。通过可视化拖拽和模型驱动,实现快速开发和部署,加速企业信息化进程。利用道一云七巧低代码平台,企业可以快速实现个性化应用开发,规范流程管理,显著提升团队协作效率。作为高生产力aPaaS平台,道一云七巧是企业数字化转型的理想选择。

欢迎关注:
官网:道一云七巧 - 可视化、智能化、数字化应用构建
免费体验:道一云产品免费试用
公众号:道一云低代码(do1info)

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

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

相关文章

C语言之线程的学习

线程属于某一个进程 共同点:都能并发 线程共享变量,进程不共享。 多线程任务中,其中某一个线程调用了exit了,其他线程会跟着一起退出 如果是特定的线程就调用pthread_exit 失败返回的是错误号 下面也是

企业为何要进行互联网收口

互联网收口又被称为网络出口收敛或网络出口整合,顾名思义,是通过技术手段将多个网络出口合并为一个或少数几个出口的过程,以优化网络性能、提高安全性和降低运营成本。在本文中,我们将深入探讨企业互联网收口的重要性,…

代码随想录-Day44

322. 零钱兑换 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数…

科普文:一文搞懂jvm原理(三)执行引擎

概叙 科普文:一文搞懂jvm(一)jvm概叙-CSDN博客 科普文:一文搞懂jvm原理(二)类加载器-CSDN博客 前面我们介绍了jvm,jvm主要包括两个子系统和两个组件: Class loader(类装载器) 子系统,Execution engine(执行引擎) 子系…

16_C语言编程基础

目录 C语言入门 程序段和代码段 C语言入门实例 英文分号(;) 注释 标识符 保留字 C中的空格 C数据类型 基本类型 sizeof获取存储字节 void类型 变量 C数组 C枚举 C中的左值(lvalue)和右值(rvalue) C常量 变量存储类型 C常用关键字(保留字) 宏定义#define co…

Codeforces Round955 (Div2)--(A~D)题解

Problem - A - Codeforces 思路&#xff1a;如果领先方互换&#xff0c;那么“NO”&#xff0c;否则“YES”。 void solve(){ Aint x1,y1; cin>>x1>>y1;int x2,y2; cin>>x2>>y2;if(x1>y1&&x2>y2||x1<y1&&…

生成式AI:未来商业的变革者

在2023年&#xff0c;生成式人工智能&#xff08;GenAI&#xff09;的浪潮席卷了全球&#xff0c;成为科技领域最炙手可热的话题之一。它不仅改变了我们与机器的互动方式&#xff0c;更在商业创新和生产力提升方面发挥了巨大的作用。本文将深入探讨2024年生成式AI的应用模式、趋…

【git】存在git LFS文件时如何处理

目录 1. 安装 Git LFS2. 初始化 Git LFS3. 跟踪大文件4. 添加和提交文件5. 克隆和拉取包含 LFS 文件的仓库 1. 安装 Git LFS 首先&#xff0c;你需要在你的系统上安装 Git LFS。你可以使用以下命令来安装&#xff1a; 在 Linux 上 # 对于基于 Debian 的系统 (如 Ubuntu) sud…

k8s 离线部署一个busybox,进而创建cronjob执行任务

首先创建一个yaml&#xff0c;创建一个名字是busybox-test的容器 apiVersion: v1 kind: Pod metadata:name: busybox-testlabels:purpose: demonstrate-busybox spec:containers:- name: busyboximage: busyboximagePullPolicy: IfNotPresentcommand:- sleep- "3600"…

docker初始化运行mysql容器时自动导入数据库存储过程问题

问题&#xff1a;用navicat导出的数据库脚本&#xff0c;在docker初始化运行mysql容器时&#xff0c;导入到存储过程时出错。 ERROR 1064 (42000) at line 2452: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for t…

面经-数据库

1.MySQL 1.1什么是MySQL? MySQL 是⼀种关系型数据库&#xff0c;在 Java 企业级开发中⾮常常⽤&#xff0c;因为 MySQL 是开源免费的&#xff0c;并 且⽅便扩展。阿⾥巴巴数据库系统也⼤量⽤到了 MySQL &#xff0c;因此它的稳定性是有保障的。 MySQL 是开放源代码的&…

Generator 是怎么样使用的以及各个阶段的变化如何

Generators 是 JavaScript 中一种特殊类型的函数&#xff0c;可以在执行过程中暂停&#xff0c;并且在需要时恢复执行。它们是通过 function* 关键字来定义的。Generator 函数返回的是一个迭代器对象&#xff0c;通过调用该迭代器对象的 next() 方法来控制函数的执行。在调用 n…

houdini 20视窗卡bug脚本开发小记

前情提要&#xff1a;houdini20面世后&#xff0c;体验非常糟糕的就是动不动资产显示不更新了。官方提供重置视窗命令&#xff0c;但设置好的拍屏参数及视窗设置也都会被重置&#xff0c;也就是解决了一个问题又带了一个问题。 所以写个脚本优化一下&#xff0c;大概思路也就是…

微尺度气象数值模拟—大涡模拟技术【WRF-LES模拟、PALM模拟】

针对微尺度气象的复杂性&#xff0c;大涡模拟&#xff08;LES&#xff09;提供了一种无可比拟的解决方案。微尺度气象学涉及对小范围内的大气过程进行精确模拟&#xff0c;这些过程往往与天气模式、地形影响和人为因素如城市布局紧密相关。在这种规模上&#xff0c;传统的气象模…

微信小程序-插槽slot

一.插槽slot 在页面使用自定义组件的时候&#xff0c;如果在自定义组件里面写子组件&#xff0c;子组件的内容无法显示。 <custom01> <text slotslot-top>你好&#xff0c;上方组件</text> 你好&#xff0c;组件 <text slotslot-bottom>你好&#xf…

elasticsearch底层核心组件

Elasticsearch是一个高度可扩展的开源全文搜索和分析引擎&#xff0c;它基于Apache Lucene构建&#xff0c;并添加了分布式特性。以下是Elasticsearch的一些底层核心组件&#xff1a; 1. **Lucene**&#xff1a; - Elasticsearch基于Apache Lucene&#xff0c;一个高性能的…

三层限流:为高并发系统保驾护航

文章目录 前言第一层限流&#xff1a;Nginx 层面的 IP 限流第二层限流&#xff1a;Gateway 对用户层级的限流第三层限流&#xff1a;微服务限流分布式限流和单机限流的优缺点&#xff1a;1、RateLimiter的使用2、Hystrix的使用3、Redislua脚本4、使用Sentinel 关于为何同时使用…

做PFMEA的经验之谈

在制造业的广袤领域中&#xff0c;PFMEA&#xff08;过程失效模式与影响分析&#xff09;是一项至关重要的工具&#xff0c;它用于识别并评估生产过程中的潜在失效模式&#xff0c;以及这些失效模式可能导致的后果。作为一名在制造业有多年经验的专业机构&#xff0c;深圳天行健…

安装KB5039212更新卡在25% 或者 96% 进度

系统之家7月1日消息&#xff0c;微软在6月11日的补丁星期二活动中&#xff0c;为Windows 11系统推出了KB5039212更新。然而&#xff0c;部分用户在Windows社区中反映&#xff0c;安装过程中出现失败&#xff0c;进度条在25%或96%时卡住。对于遇到此类问题的Windows 11用户&…