RESTful API 设计指南——开篇词

news2024/11/20 22:38:36

引言

十年后的今天,我终于学会了RESTful API。

以上,就是我最近一个月的心路历程。入职新公司不到2周,自己都还没完全理解RESTful API就要求给校招应届生培训,着实压力山大。培训结束后也感觉收获颇丰,遂总结分享出来,希望对你有所帮助。

网上的文章比较零散,大多数讲 RESTful API 都是浅尝辄止,看完后我的印象只停留在 HTTP方法代表操作(如GET表示查询)、HTTP状态码代表结果(如200代表成功)等很浅的层面。
经过这些年的发展,特别是自 2015年 Swagger 规范更名为 Open API 后,一直到 OpenAPI 3.0.0 第一个正式版本的推出,陆陆续续类似 VS Code 和 PostMan 等工具开始涌现支持其语法的各种插件,到目前落地 RESTful API 变得越来越简单。

于是,我决定写一个系列文章,来记录和分享 RESTful API 设计的相关心得,也算是给自己一个交代:到现在才初步学会 RESTful API,这么些年,我都在干什么啊?

REST 和 Web

2000年,HTTP规范的主要作者之一,菲尔丁发表了博士论文《基于网络的软件体系结构风格与设计》,首次提出了名为“表现层状态转移”(REST)的互联网体系架构:

但是直到2008年,《RESTful Web Services》一书的推出,才系统性的讲述了如何设计REST式API风格:

在本书中,作者将其称之为面向资源的架构(Resources-Oriented-Architecture,简称ROA),这也是本书的最大亮点,补齐了我在 RESTful 理论知识方面的不足:

ROA(面向资源的架构) 和 OOP(面向对象编程)的思想有点类似(一切都是资源 vs 万物皆对象),主要强调如何利用 HTTP 应用层协议来操作这些资源,实现资源的增删改查。

不过到真正流行起来,成为 HTTP API 的事实上的标准风格规范,应该是从 Github 和 Google 开放的 API 使用 RESTful 风格开始(大概在2012年以后),才纷纷引得其他各大国内外互联网公司深入研究和使用。

但很奇怪的是,至今为止,我去看了 高德地图WebAPI、企业微信API 和 阿里云部分API,实际使用 RESTful 风格的互联网公司可能并没有那么多,这可能是为什么面试中很少会有面试官问 RESTful 和 API 设计的相关问题(可能他们也不懂)。

那么,既然面试用不到,还有啥必要学这个东西?

面试会考代码规范吗?不会,重要吗?我认为很重要,所以 RESTful 本质上就是一种规范,一种专门用于 HTTP API 设计的规范。既然是规范,主要的作用就是统一习惯和做法:大家都使用普通话交流!而不是到了一个新的公司,加入一个新的团队,需要学习一门新的方言!

下面让我们看看没有规范时,我们会遇到那些 API 设计问题!

那些年的 API 设计疑问

声明:虽然作者提倡使用 RESTful 规范来设计 HTTP API,但是目前国内互联网大厂都不统一,故我们应当理解下面介绍的案例,其必定有自己的背景和理由。

所有的接口都使用Post请求

你可能听过或者刷到过这样的段子,同样 v2ex 上也有这样一个 帖子,讨论的热火朝天:

对接同事的接口,他定义的所有接口都是 post 请求,理由是 https 用 post 更安全。

之前习惯使用 restful api ,如果说 https 只有 post 请求是安全的话?那为啥还需要 get 、put 、delete ?我该如何反驳他。

其中网友的回复有以下几种观点:

  • POST挺好的,就应该这么干,沟通少
  • 一把梭,早点干完早点回家
  • 吵赢了又怎么样?工作而已,优雅不能当饭吃。虽然评论没有一边倒,但是也有大量的人支持

我搜索了下,觉得这个 回答 比较靠谱点:

  • 如果你的团队都是大佬,或者有着良好的团队规范,所有人都在平均水平线之上,并且有良好的纠错机制,那基本不会制定这样的规则。但如果团队成员水平参差不齐,尤其是小团队,创业团队,常常上来就开干,没什么规范,纯靠开发者个人素质决定代码质量,这样的团队就不得不制定这样的规范。
  • 毕竟可以减少非常多的问题,Post不用担心URL长度限制,也不会误用缓存。通过一个规则减少了出错的可能,这个决策性价比极高。
  • 造成的结果:公司有新人进来,什么垃圾公司,还有这种要求,回去就在群里讲段子。
  • 实际上都是有原因的,有些外包公司或者提供第三方接口的公司也会选择只用Post,就是图个方便。

通过上面的一些回答,我认为比较合理的是外包公司可能会有这种规定,领导不想花力气培养新人,直接一把梭省事,避免犯错的同时还能节省学习成本

但程序员宝贵的不就是这些经验教训吗?所以,这个规定的受益方是公司,对个人而言没有任何好处:它没有让你学习到任何有用的知识!甚至会让你误认为HTTP就应该这样干,从而失去了深入学习 HTTP 和 RESTful API 的机会

我们会在下一章中深入探讨这个问题。

不管成功还是失败,HTTP状态码都返回200

HTTP 是请求-响应的通讯模型,对于客户端的请求操作,服务端需要告诉客户端操作结果,有 2 种方式:通过 HTTP 状态码 或者在响应的 JSON 数据中增加一个 错误码 来代表操作结果。

前者需要理解 HTTP 各状态码的含义,有一定的学习成本,而后者上手简单,所以工作经验不多的人大概率会使用第二种方式。

也就是在返回结果中增加一个字段来代表结果,此时,不管请求成功还是失败,服务端返回的 HTTP 状态码都是 200 OK,具体的业务结果,需要解析 JSON 数据,根据其中类似 errorCode 的字段进一步判断,以新增用户接口为例:

请求:

POST /userManager/addUser
{
   "userName":"admin",
   "nickName":"管理员",
   "userPwd":"pwd"
}

{
   "errorCode":0,
   "errorMsg":"success"
}

如果是查询类的接口,则除了错误码和错误描述外,响应结果中还会多出一个 data 字段,用来放实际的业务数据:

{
   "errorCode":0,
   "errorMsg":"success",
   "data":{
      "total":0,
      "entries":[]
   }
}

这样的做法有2个缺陷:

  • 数据冗余:HTTP 是应用层协议,已经有状态码表示操作结果了,我们又定义一个,未免太多余,白白多花流量钱,浪费带宽
  • 重复造轮子:为了区分不同的错误原因,我们要精心规划 errorCode ,比如0代表成功,1000-2000 代表一种失败原因,2000-3000代表另外一种。有没有发现其实 HTTP 本身已经给我们设计好了?2xx代表成功,3xx跳转,4xx代表客户端原因导致的错误(参数非法),5xx代表服务端出错

除此之外,这种做法最大的问题是(来自左耳朵耗子的这篇文章):监控系统在一种低效的状态下工作,它需要把所有的网络请求包打开后才知道是否是错误,而且完全不知道是调用端出错还是服务端出错。于是一些像重试或熔断这样的控制系统完全不知道怎么搞(如果是 4xx 错误,那么重试或熔断是没有意义的,只有 5xx 才有意义)。

我们会在下一章进一步探讨这个问题,为什么不建议你这样做,特别是微服务时代。

PS:千万别学我,这么些年我都是这样干的,我深表惭愧

API命名千奇百怪

如果我们不使用 HTTP 方法(或者只使用 GET 和 POST)来代表具体的增删改查,那么我们只能在 URI 上下功夫,来设计和命名我们的 API,通过一系列的规则来说明这个 API 的作用。

比如我们先用前缀说明 API 的主要功能,紧接着用 动词 来代表具体的操作:新增是add,删除是delete,修改是update,但是查询的翻译就难了,有些人用query,有些人有select。

以新增员工 API 举例,可能会出行如下情况:

http://localhost/employee/save
http://localhost/employee/add
http://localhost/employee/new
http://localhost/employee/xinzeng
http://localhost/employee/append
http://localhost/employee?cmd=add

为什么 API 命名千奇百怪?甚至上述示例中最后一种把具体的操作放到了 query 参数中表示?这是因为开发者对API接口设计的习惯不同,单词翻译也可能不一样,而且请求方法和响应结果可能也是很随意的。

所以,如何设计一套科学的API接口?答案:具有 RESTful 风格的API接口

REST 和 RESTful API 的关系

网络上经常会有人搞混,分不清 REST 和 RESTful API 的关系,所以有必要科普一下。

简而言之:REST 是规范,而 RESTful API 是满足这些规范的 API 接口

REST(Representational State Transfer)表现层状态转移,是一种架构风格,由 Roy Fielding 在他的博士论文《Architectural Styles and the Design of Network-based Software Architectures》里提出。

REST 本身并没有创建新的技术、组件或服务,它只是一种软件架构风格,是一组架构约束条件和原则,而不是技术框架。

而 RESTful API 特指满足这些规范的 HTTP API 接口。

所以只要你的 HTTP 接口使用 POST/DELETE/PUT/GET 代表增删改查操作,使用 HTTP 状态码代表结果,使用 URI 代表操作对象,你的 API 就是 RESTful API

REST 和 HTTP 的关系

REST 规范把所有内容都视为资源,一切皆资源,故 REST 架构对资源操作的操作包括获取、创建、修改和删除,这些操作正好对应 HTTP 协议的 GET、POST、PUT 和 DELETE 方法,HTTP 动词与 REST 风格 CRUD 的对应关系见下表:

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

总结

本章我们向大家推荐了一本书籍 《RESTful Web Services》,通过阅读 "第4章 面向资源的架构"我们可以补足 RESTful API 理论知识(我很少看到有人推荐这本书)。

我们通过对比 REST、RESTful API 和 HTTP 的关系,以及给出了 REST 风格架构的出处(博士论文),让大家初步了解了 RESTful API 的前后今生。

在文章的中间部分,我们阐述了没有 API 规范的情况下,可能会遇到的3个问题:

  • 所有的接口都使用Post请求
  • 不管成功还是失败,HTTP状态码都返回200
  • API命名千奇百怪

这几个问题通常发生在不同的公司、不同的团队,如果你跳槽过几次,可能会遇到类似的问题。不同的公司有不同的API规范(大部分没有),我们最好使用在全世界范围内的主流规范风格(RESTful API),避免不必要的口水,最主要的是能得到成长,对于我们这些普通人,成长就是一切。

在后续的文章中,我会:

  • 分析上面做法的优劣
  • 介绍目前公司在使用的 API 规范,你可以直接拿过去用
  • 介绍 OpenAPI 规范和 API 开发工具,以及 MQ 异步 API 规范
  • 介绍几个实战案例,带你入门 RESTful API 设计
  • 解读和介绍主流 Azure 和 Google 团队的 RESTful API 规范

未完待续……

参考:

  • 为什么有公司规定所有接口都用Post?
  • 一把梭:REST API 全用 POST?
  • 对接同事的接口,他定义的所有接口都是 post 请求,理由是 https 用 post 更安全
  • 12 | API 风格(上):如何设计RESTful API?

作者简介:一线Coder,公众号《Go和分布式IM》运营者,开源项目: CoffeeChat 、interview-golang 发起人 & 核心开发者,终身程序员。

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

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

相关文章

JavaSwing实现银行账户交易系统(含教程)可加数据库 Java课程设计

8.银行账户交易系统 视频教程: 【课程设计】银行账户交易系统-Java Swing-你的课程我设计 功能描述: 系统有银行柜员和普通用户两个角色; 银行柜员登录后可查看用户账号信息、开户、修改账户、存钱、取钱、注销账户、查看交易记录; 用户登录…

【旅游行业】Axure旅游社交平台APP端原型图,攻略门票酒店民宿原型案例

作品概况 页面数量:共 110 页 兼容软件:Axure RP 9/10,不支持低版本 应用领域:旅游平台,酒店住宿 作品申明:页面内容仅用于功能演示,无实际功能 作品特色 本作品为「旅游社交平台」移动端…

lenovo联想笔记本ThinkPad P1 Gen5/X1 Extreme Gen5原装出厂Windows11预装OEM系统

链接:https://pan.baidu.com/s/13E97Nwc-0-N7ffPjEeeeOw?pwdep4l 提取码:ep41 原装出厂系统自带所有驱动、出厂主题壁纸、Office办公软件、联想电脑管家等预装程序 所需要工具:32G或以上的U盘 文件格式:ISO 文件大小&#xff…

数据结构中树、森林 与 二叉树的转换

1 树转换为 二叉树 将树转换成二叉树的步骤是: 加线。在所有的兄弟结点之间加一条线。去线。对于树中的每个结点,只保留它与第一个孩子结点的连线,删除该结点其他孩子结点之间的连线。调整。以树的根结点为轴心,将整个树顺时针旋…

微信小程序校园运动场预约系统xuvvt

本论文的内容是关于运动场预约,主要内容不仅包括了小程序的分析和设计还对几个主要模块进行详细阐述与分析。此微信小程序运动场预约分为管理员操作和教师操作、学生操作。学生的操作主要是可以在网页上浏览到场地信息、运动视频、心情动态等功能,用户可…

护眼灯买哪种好?考研必备的护眼台灯推荐

家里顶灯太暗了且高度太高,还是原始的LED灯,晚上用着眼睛都有点难受,还好遇到了儿童护眼灯。下面小编为大家介绍下儿童护眼灯哪个牌子好?什么护眼台灯比较专业 1、色温 台灯的色温也是一个需要考虑的因素,所谓的色温其…

机器学习与计算机视觉 D2

整合为学习笔记!参考阅读了几位大佬的作品,已标注出处~ 机器学习的数学基础 线性与非线性变换 从几何意义上,线性变换表示的是直线的特性,符合两个性质: 变换前后零点不变,变换前后直线还是直线。 线性变换意味着可以…

从字典到 CookieJar 的转换技巧

在使用requests库进行HTTP请求时,经常需要传递cookies参数来实现一些特定的功能,例如保持用户会话状态或者进行身份验证。 在HTTP请求中,Cookie是一种用来在客户端和服务器之间传递状态信息的方式,通常用于记录用户的身份验证信息…

Linux中,查看Tomcat版本、如何查看Tomcat版本

方法 在tomcat的bin目录下,执行version.sh命令即可 结果

XmlElement注解在Java的数组属性上,以产生多个相同的XML元素

例如&#xff0c;下面这段XML数据&#xff0c;有多个data元素&#xff0c;并且它们级别相同: <?xml version"1.0" encoding"UTF-8"?><request><reqtype>05</reqtype><secret>test</secret><body><userid&…

sortablejs拖拽后新增和删除行时顺序错乱

问题描述&#xff1a;如下图所示&#xff0c;使用sortablejs拖拽后&#xff0c;在序号2后新增行会出现新增行跑到第一行的错误顺序。 解决&#xff1a;在进行拖拽后&#xff0c;对表格数据进行清空重新赋值。

Permute3(万能音视频转换器)

Permute是一款Mac平台上的媒体格式转换软件&#xff0c;由Chaotic Software开发。它可以帮助用户快速地将各种音频、视频和图像文件转换成所需格式&#xff0c;并提供了一些常用工具以便于用户进行编辑和处理。 Permute的主要特点包括&#xff1a; - 支持大量格式&#xff1a;支…

谈谈Redis中的多路复用

目录 前言 什么是多路服用 Redis中的多路复用 Redis单线程&#xff1f;多线程&#xff1f; 前言 redis是单线程的&#xff08;不严谨的讲法的哈&#xff09;&#xff0c;为什么还这么快&#xff0c;很多人相信会回答因为redis是基于内存操作的, 内存的读写速度是非常快的。…

ADE XL 工艺角corner仿真

在ADE L界面打开ADE XL 建立一个新的ADE XL 点击click to add corner 添加工艺角 点击图标添加三个工艺角 点击model files里面的click to add 添加model 文件。点击import from tests&#xff0c;点击ok 填好红框内容&#xff0c;点击ok 可以看到添加好的工艺角&#xff0c;双…

MySQL 数据库下载

1 最新版 MySQL :: Download MySQL Community Server 2 存档版本(Archived Versions)-历史版本 MySQL :: Download MySQL Community Server (Archived Versions) 3 下载(样例: zip 方式) 说明&#xff1a; 可以下载安装文件的方式&#xff0c;也可以使用压缩包方式&#xff…

leetcode 每日一题复盘(11.20~11.26)

leetcode 746 使用最小花费爬楼梯 虽然是简单题但还是要说一下,感觉做题的思路还是不够清晰,好的是知道状态是最低花费,知道围绕所求的目标进行展开,倒推出递推公式 一开始写的递推公式是dp[i]dp[i-1]min(cost[i-2],cost[i-1]),写出了一个类似贪心算法的东西,归根结底还是对dp…

智慧城市科普:最近很火的概念“智慧城市 ”到底是啥?

在当今飞速发展的数字时代&#xff0c;智慧城市的兴起成为城市管理与科技创新的焦点。本文将深入科学原理和技术细节&#xff0c;揭示智慧城市的奥秘&#xff0c;以及它对城市未来发展的深远影响。 1. 智慧城市的概念&#xff1a; 智慧城市并非抽象的未来愿景&#xff0c;而是…

解决 requests 库中 verify 属性问题的方法

在使用 Python 的 requests 库进行网络请求时&#xff0c;我们常常需要确保通信的安全性&#xff0c;这涉及到验证服务器的 SSL/TLS 证书。 这个问题的背后是 requests 库的设计&#xff0c;为了解决这个问题&#xff0c;我们可以考虑修改 requests 库的源代码&#xff0c;以确…

模具制造厂ERP都有哪些牌子?模具制造厂ERP有什么用

模具制造通常会涉及物料领用、成品入库、工艺流转、投入水口、配方、模具、生产啤数统计等众多环节&#xff0c;各个环节数据的实时和准确传递&#xff0c;有利于企业清晰掌握订单生产进度&#xff0c;及时调整制造策略等。 有些模具制造工厂采用传统的管理模式&#xff0c;随…

【Docker】从零开始:2.Docker三要素

【Docker】从零开始&#xff1a;2.Docker三要素 DockerDocker支持的系统CentOS DockerDocker三要素Docker镜像(Image):Docker容器(Container):1.从面向对象角度2.从镜像容器角度 Docker仓库(Repository) 总结 Docker docker官网&#xff1a;http://www.docker.com 仓库-Docker…