RESTful API 设计指南——开篇词

引言

十年后的今天,我终于学会了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 发起人 & 核心开发者,终身程序员。

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

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

相关文章

cpupower命令

Linux 内部共有五种对频率的管理策略 userspace , conservative , ondemand , powersave(省电模式) 和 performance(性能模式)。 performance: 顾名思义只注重效率,将CPU频率固定…

【AI实用技巧】GPT写sql统计语句

编写sql的统计语句是一项复杂的任务,特别是涉及多表的情况下。但有了GPT的帮助,一切变得轻松愉快。 AI7号 - 最强人工智能(GPT)中文版https://ai7.pro/s/9v2um 举例说明 有表结构如下: users(user_id, name) bills(…

CRM系统的客户细分有什么作用?

我们常常说,企业想要开展有针对性的营销活动,就需要进行客户细分。通过特定条件,将客户分为几类,从而对不同类型的客户提供不同的产品和服务。下面我们就针对这里来详细说说,CRM中客户细分是什么?如何细分客…

ADB安装及使用介绍

一、ADB简介 1、什么是adb ADB 全称为 Android Debug Bridge,起到调试桥的作用,是一个客户端-服务器端程序。其中客户端是用来操作的电脑,服务端是 Android 设备。 ADB 也是 Android SDK 中的一个工具,可以直接操作管理 Android …

Linux安全之AIDE系统入侵检测工具安装和使用

一、AIDE 系统入侵检测工具简介 AIDE,全称为Advanced Intrusion Detection Environment,是一个主要用于检测文件完整性的入侵检测工具。它能够构建一个指定文件的数据库,并使用aide.conf作为其配置文件。AIDE数据库能够保存文件的各种属性&am…

出版级柱状图绘制,轻松拿捏(初学者友好的R包ggpubr在线版)

工具地址 Galaxy中国(UseGalaxy.cn) > Graph/Display Data > 柱状图 功能描述 这个工具可以绘制出版级柱状图,是 ggpubr 包的 barplot 工具的在线版。 条形图通过垂直或水平的条形展示分类变量的分布(频数)。横坐…

九宫格 图片 自定义 路径

<image :src" ../../static/img/ item.urlname .png " class"u-w-82 u-h-82 u-p-t-36"></image>使用场景&#xff1a;九宫格里含有多张图片 html <view class"u-p-b-46 u-p-x-35"><u-grid :border"false" c…

element表格分页+数据过滤筛选

目录 前言效果展示分页效果展示搜索效果展示 代码分析分页功能过滤数据功能 全部代码 前言 在el-element的标签里的tableData数据过多时&#xff0c;会导致表格页面操作卡顿。为解决这一问题&#xff0c;有以下解决方法&#xff1a; 分页加载&#xff1a; 将大量数据进行分页&…

Django 入门学习总结8-管理页面的生成

修改polls/admin.py文件为&#xff1a; from django.contrib import admin from .models import Choice, Question class ChoiceInline(admin.StackedInline): model Choice extra 3 class QuestionAdmin(admin.ModelAdmin): fieldsets [ (None, {&q…

系列十四、异步回调

一、概述 二、案例代码 /*** Author : 一叶浮萍归大海* Date: 2023/11/21 10:45* Description: 异步任务案例代码*/ public class CompletableFutureMainApp {public static void main(String[] args) throws ExecutionException, InterruptedException {CompletableFuture<…

WMS仓库管理系统的应用场景有哪些?

“WMS仓库管理系统的应用场景有哪些&#xff1f;” WMS&#xff08;仓库管理系统&#xff09;作为一种强大的工具&#xff0c;它在提升仓库操作效率、优化库存管理以及改善供应链可视性方面发挥着关键作用。那么&#xff0c;WMS究竟在哪些场景下展现出强大的应用价值呢&#x…

【HarmonyOS】低代码平台组件拖拽使用技巧之列表

【关键字】 HarmonyOS、低代码平台、组件拖拽、列表、列表项 1、写在前面 我们在日常开发中使用最多的组件可能就是列表组件了&#xff0c;现在几乎所有的应用都离不开列表&#xff0c;那么今天我们就来介绍一下如何利用低代码平台来实现列表的展示&#xff0c;列表实际上也是…

react重要知识点(面经)

react重要知识点&#xff08;面经&#xff09; react生命周期classhooks reduxredux 核心概念redux 计数器案例 react页面加载卡顿使用懒加载异步加载JavaScript压缩和缓存静态资源使用React.memo() PubSub使用方式1.1 react导入库1.2 react 页面引入pubsubjs1.3 pubsubjs使用2…

高斯分布。

(5 封私信 / 80 条消息) 正态分布 - 搜索结果 - 知乎 (zhihu.com)https://www.zhihu.com/search?typecontent&q%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83正态分布&#xff08;Normal Distribution&#xff09;&#xff0c;也称常态分布&#xff0c;又名高斯分布&#xff08;G…

(影视源码)最新苹果CMS海螺影视V20模板源码/影视网站程序源码/后台全修复版+广告代码添加与优化

源码简介&#xff1a; 这个是2023最新苹果CMS海螺影视程序模板源码&#xff0c;V20电影影视网站源码&#xff0c;它后台全修复版广告代码添加与优化。海螺模板一直是苹果cms比较好看的模板。苹果CMS就是影视解析的PHP源码&#xff0c;站长朋友可以拿去搭建一个影视站引流&…

Python运维监控系统之架构设计

说起Python这门编程语言的作用&#xff0c;可以列举很多方面&#xff0c;其实每一门流行的编程语言都可以列举很多方面&#xff0c;但是要说起Python的主要领域&#xff0c;莫过于运维监控方面&#xff0c;在这方面有大量优秀的开源运维系统。 虽然有很多优秀的开源运维监控系统…

算法设计与分析算法实现——删数问题

通过棋盘输入一个高精度的正整数n(n的有效位数<=240)去掉其中任意s个数字后,剩下的数字按原左右次序将组成一个新的正整数。变成对给定的n和s,寻找一种方案,使得剩下的数字组成的新数最小。 输入:n,s 输出:最后剩下的最小数 输入实例: 178543 4 输出示例: 13 首先…

U盘恢复怎么做?3个宝藏方法分享!

“我经常都会把各种数据保存在u盘中&#xff0c;但是不知道为什么&#xff0c;有时候经常会出现u盘数据丢失的情况。有什么方法可以恢复U盘吗&#xff1f;请朋友们给我出出主意吧&#xff01;” 由于u盘的小巧便捷&#xff0c;很多用户都会选择将文件保存在u盘中。但是在使用u盘…

Windows10环境下Python解析pacp文件

Windows10环境下Python解析pacp文件 一、背景 在Python中,你可以使用scapy库来解析pcap文件。scapy是一个功能强大的网络分析工具,可以用于解析、构建和发送网络数据包。 二、环境安装 命令在终端中安装: pip install scapy由于我使用的Pycharm,所以我就直接在Python Int…

Java零基础-Mybatis篇

【Mybatis】 1.JDBC不足 JDBC作为Java操作数据库的模板&#xff0c;如果想要对数据库进行操作&#xff0c;必须使用JDBC&#xff0c;但是在使用JDBC进行数据库操作时&#xff0c;重复代码多&#xff0c;动态SQL构建繁琐&#xff0c;将查询结果转化为对象&#xff0c;相当麻烦…