《细说PHP》第四版 样章 第23章 自定义PHP接口规范 6
23.4 API的设计原则和规范
API是服务提供方和使用方之间对接的通道,前面我们设计的一些简单API的例子,基本上比较随意,没有使用任何规范。设想一下,每个平台都可能存在大量的API,如果API设计没有原则,也没有统一的规范,按开发者的意愿随意编写,访问千差万别的API,不仅让API的使用非常麻烦,对API的改动也会导致项目或移动App无法工作。当然,一个好的规范对于解决这些事情能起到事半功倍的作用。如果想让服务端的价值更好地体现出来,就要好好设计API。通过使用规范的API,我们的服务或核心程序将有可能成为其他项目所依赖的平台。我们提供的API越易用,就会有越多人愿意使用它。
23.4.1 什么是RESTful风格的API
现在不管是开发移动应用,还是基于前后端分离,企业在设计API时都会遵循RESTful风格。REST(Representational State Transfer)定义了一套基于Web的数据交互方式的设计风格,符合REST风格的API就可以叫作RESTful API,REST只是风格没有标准,是目前最流行的一种互联网软件架构。它结构清晰、符合标准、扩展方便,基于这个风格设计的软件可以更简洁、更有层次、更易于实现缓存等机制,所以越来越多的网站和项目开始采用RESTful风格。Web应用程序的API设计,最重要的REST原则是,客户端和服务器之间的交互请求之间是无状态的。从客户端到服务器的每个请求,都必须包含理解请求所必要的信息。
23.4.2 RESTful API应遵循的原则
一次完整的API调用过程,所涉及的每个环节都需要设计为统一的风格,包括客户端使用的HTTP方法、URI的格式、返回数据的结构等,都应遵循RESTful API的原则。
1. 协议
API与用户的通信协议,尽量使用HTTPs协议。使用HTTPs协议和RESTful API本身没有多大关系,但是对于增加网站的安全性是非常重要的,特别是如果提供的是公开的API,那么HTTPs就更显得重要了。因为HTTPs协议的所有信息都是加密传播的,第三方无法窃听,具有校验机制,一旦被篡改,通信双方会立刻发现,配备身份证书,防止身份被冒充。如果做不到全部都使用HTTPs协议,也一定要在项目的登录和注册的接口上使用。因为在这两个接口用户还没有登录系统,没有获取用户身份,是最容易被窃听的。其他登录后才需要访问的API可以使用HTTP协议。
2. 域名
请求API的URL中除了协议外, 请求的根地址也很重要,一个好的软件架构,最好要让API的系统可以有单独的访问通道。应该尽量将API部署在专用的域名下面,例如:
https://api.ydma.com
如果确定API很简单,不会有进一步的扩展,可以考虑把API放在子域名下面,例如:
https://ydma.com/api/
3. 版本
在设计API时一定要有版本规划,以便以后API的升级和维护。应强制性规划API版本,不要发布无版本的API。在使用简单数字时,避免有小数点,如v3.5。应该将API的版本号放入URL中,如下所示:
https://api.ydma.com/v1/
当然,也可以将版本号放在HTTP的头信息中, 但不如放入URL方便和直观。
4. 路径
路径表示API的具体网址URL,在RESTful架构中,每个网址代表一种“资源”的存放地址,所以网址中不能有动词,只能有名词,而且名词一般都应该与数据库的表和字段对应且使用复数,例如:
https://api.ydma.com/v1/courses // IT云课堂的所有课程,代表多个资源
https://api.ydma.com/v1/courses/1/php // id为1的课程中的所有PHP课程,代表多个资源
https://api.ydma.com/v1/courses/1 // 代表单个资源,id为1的课程
https://api.ydma.com/v1/courses/1;2;3 // 代表单个资源,id为1、2、3的课程
URL中“/”表示层级,用于按“资源实体”的关联关系进行对象导航,一般跟进id导航。过深的导航层级容易导致URL膨胀,不易维护,如https://api.ydma.com/v1/ courses/1/web/3/php/4,尽量使用查询参数代替路径中的实体导航。
注意:根据RFC3986定义,URL是区分大小写的,所以应该尽量使用小写字母来命名!
5. 请求方法
有了“资源”的URL设计,所有针对资源的操作,都用指定的HTTP动词,HTTP常见的操作动词如表23-2所示。
表23-2 HTTP常见的操作动词
注意:GET方法和查询参数不应该涉及状态改变。应使用PUT、POST和DELETE方法而不是GET方法来改变状态。PUT更新单个资源(全量),由客户端提供完整的更新后的资源。与之对应的是 PATCH,PATCH 负责部分更新,由客户端提供要更新的字段。
6. 过滤信息
如果数据量太大,服务器不可能将所有数据返给用户。API应该提供参数来过滤返回结果,为集合提供过滤、排序、选择和分页等功能。如表23-3所示,是URL中常见的过滤信息。
表23-3 URL中常见的过滤信息
另外,在移动端开始时,由于移动设备的显示空间小,只能显示其中一些必要的字段,其实不需要接口返回一个资源的所有字段,给API一个选择字段的功能,这会降低网络流量,提高API的可用性,例如:
GET https://api.ydma.com/v1/users?fields=id,username,sex&state=open&sort=age // 获取三个字段
7. 固定返回码
在HTTP头部报文构成中,字段“status code”很重要。它说明了请求的大致情况,是否正常处理、出现了什么错误等。状态码都是3位数,大概分为以下几个区间,如表23-4所示。
表23-4 HTTP 状态码区间说明
我们在使用RESTful API时需要使用返回码的原因大致如下,客户端在调用一个API之后,接收到的反馈必须能够标识这次调用是否成功,如果不成功,客户端需要得到执行失败的原因。我们可以在API设计时做一个小小的约定,就能完美的满足自己的需求了。REST的大部分实现都是基于HTTP的,那么自然而然就少不了与返回码打交道。遗憾的是,HTTP的返回码的定义很多,也很烦琐,信息表达还不够详细,和实际开发中用到的状态含义还有些差距。虽然很多公司的开发组都直接使用HTTP的状态码,但笔者建议,根据项目自身去自定义一些状态码和对应的错误返回信息会更适用一些,如表23-5所示。
表23-5 自定义状态码参考
尽可能提供准确的错误信息,如数据格式不正确、缺少某个字段等,而不是直接返回“请求错误”之类的信息。
8. 固定返回结构
现在,越来越多的API设计会使用JSON来传递数据,本章也以JSON为例。只要调用成功,服务器端必须响应数据,而响应数据的格式在任何情况下都应当是一致的,这样有利于客户端处理返回结果。自定义服务器端所有的响应格式如下:
成功返回的消息结构
失败返回的消息结构
{
"code": 0,
"message": "",
"time":1527158707,
"data":{"id":"1","username":"高洛峰","sex":"男","age":"30"}
}
{
"code": E002,
"message": "无效的请求",
"time":1527158402,
"data":{ }
}
它们的含义如下:
Ø code为0代表调用成功,其他是自定义的错误码。
Ø message表示在API调用失败的情况下详细的错误信息,这个信息可以由客户端直接呈现给用户,否则为空。
Ø time 返回的是服务器动态时间,通过这个时间的变化,让用户知道重新请求过服务器。
Ø data表示服务器端返回的数据,具体格式由服务器端自定义,API调用错误则为空。
REST风格的API会针对不同操作,服务器向用户返回的不同结构的结果,需要符合以下规范,但笔者认为这样比较烦琐,如下所示:
GET https://api.ydma.com/v1/collection
GET https://api.ydma.com/v1/collection/resource
POST https://api.ydma.com/v1/collection
PUT https://api.ydma.com/v1/collection/resource
PATCH https://api.ydma.com/v1/collection/resource
DELETE https://api.ydma.com/v1/collection/resource
#返回一个资源对象的列表
#返回一个资源对象
#返回新创建的资源对象
#返回一个完整的资源对象
#返回一个完整的资源
#返回一个空文档
9. 编写文档
API最终是让人使用的,无论是对内还是对外,即使遵循上面提到的所有规则,API设计得很优雅,有时候用户还是不知道该如何使用它们。因此,编写清晰可读的文档是很有必要的。另外,编写文档也可以作为产出的一部分,以及用来记录,以方便查询参考。项目组中常用的API文档结构如图23-10所示。
图23-10 项目组中常用的API文档结构
当然,如果单独管理API文档是比较麻烦的,我们可以借助工具来管理,如国内比较不错的平台www.showdoc.cc,可以在该平台上注册一个账号管理接口文档,也可以独立搭建网站来管理,下载地址 https://www.getpostman.com/。该工具不仅可以管理文档,还可以模拟HTTP请求,当作应用接口的客户端来使用,操作比较简单,还可以模拟GET、POST等请求接口,也能查看响应结果,针对 JSON 格式的数据还提供解析功能。
《细说PHP》第四版 样章 第23章 自定义PHP接口规范 6的更多相关文章
- 《细说PHP》第四版 样章 第二章 PHP的应用与发展 1
<细说PHP>第四版 样章 第二章 PHP的应用与发展 1 学习任何编程语言之前,先了解一下它的应用与发展是很有必要的.从Web开发的历史看来,PHP.Python和Ruby几乎是同时出现 ...
- 《java编程思想(第四版)》第一二章学习笔记
目录 一.Introduction 1.抽象过程 2.面向对象语言(包括Java)的五个基本特性 3.每个对象都提供服务 4.public.private.protected三者的区别 5.Java的 ...
- 《细说PHP》 第四版 样章 第二章 PHP的应用与发展 5
2.5 如何学习PHP PHP以其简单易学的特点,以及敏捷开发的优势,从一个几乎不被人知的开源项目,慢慢成长为技术人员首选的动态Web设计工具,与其他语言相比,PHP表现得更好.更快.更简单易学.尽 ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 11
23.6 使用第三方接口服务实例 接供服务的第三方接口平台有很多,现在的项目中也经常用到一些第三方接口,如支付宝.微信.短信.邮件接口等,我们需要借助第三方的能力来实现产品的某些功能.如果自己已经掌 ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 9
23.5.3 WebAPI框架应用 程序框架其实就是一个半成品项目,在应用框架时,核心的服务程序只应用,不需要改动.当然如果有必要,也可以根据项目的需要对框架进行二次开发.本节内容主要基于我们的框架 ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 8
23.5.2 架构详解 本例的实现最重要的就是服务层的设计,有两个配置文件config.php和api.php,其中文件config.php是全局的配置文件,用于整个程序全局需要的参数设置.可以根据 ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 3
23.2 接口实现的基础 大家都很了解函数在本地应用,通过名称调用函数执行,并通过传递不同参数,函数有不同执行,执行后给调用者返回结果.如果把一个函数做成一个接口远程访问,也需要这几个步骤.使用HT ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 1
如今的项目开发中,接口是很普遍的应用技术.现在好多项目组都单独设有接口开发人员.像腾讯.微博.淘宝等开放平台,其所谓的开放,就是提供一些可调用的接口,用于获取相关的信息.例如,微信用户基本信息.淘宝店 ...
- 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 12
18.9 管理表books实例 在Web项目中,几乎所有模块都要和数据表打交道,而对表的管理无非就是增.删.改.查等操作,所以熟练掌握对表进行管理的这些常见操作是十分有必的.本例为了能更好地展示PD ...
随机推荐
- windows系统搭建zookeeper
安装&配置 在apache的官方网站提供了好多镜像下载地址,然后找到对应的版本 下载地址: http://mirrors.cnnic.cn/apache/zookeeper/zookeeper ...
- 通过 Telegraf + InfluxDB + Grafana 快速搭建监控体系的详细步骤
第一部分 Telegraf 部署和配置 Telegraf 是实现 数据采集 的工具.Telegraf 具有内存占用小的特点,通过插件系统开发人员可轻松添加支持其他服务的扩展. 在平台监控系统中,可以使 ...
- Redis内存数据库在Exchange会议室的整体应用架构
注:本文是别人写的,感觉写得很好就转过来,版权归原作者所有哦,谁知道出处可以告诉我,谢谢. 根据以上的会议室应用现状分析,该架构的核心是把历史发生的会议室申请数据定时同步到Redis内存数据库中,对于 ...
- 2019年全国高校计算机能力挑战赛初赛C语言解答
http://www.ncccu.org.cn 2019年全国高校计算机能力挑战赛分设大数据算法赛,人工智能算法赛,Office高级应用赛,程序设计赛4大赛项 C语言初赛解答 1:编程1 16.现有一 ...
- C和C++常见误区以及问题整理
c和c++的关系 c是面向过程的语言,c++是在c的基础上扩展的面向对象的编程语言. c++具备c的所有功能,对c的库完全兼容. c++的标准在98年确定,在那之前已经有一些库大量使用. 新标准中,推 ...
- tensorflow-- Dataset创建数据集对象
tf.data模块包含: experimental 模块 Dataset 类 FixedLengthRecordDataset 类 TFRecordDataset 类 TextLineDataset ...
- 资深程序员告诉你为什么要用Python3而不是Python2
经常遇到这样的问题:<现在开始学习python的话,是学习python2.x还是学习python3.x比较好?>,这也是许多初学者会遇到的问题,我们的答案是python 3.x. 为了帮助 ...
- PlayJava Day017
今日所学: /* 2019.08.19开始学习,此为补档. */ 1.数组变量 a.数组变量是数组的管理者而非数组本身 b.数组必须创建出来然后交给数组变量来管理 c.数组变量之间的赋值是管理权限的赋 ...
- 如何获取input,file里的文件,实现预览效果,并传给后端?
单纯的事件与获取 <input type="file" name="file" id="fileUpload"> <img ...
- Android 单选列表对话框 setSingleChoiceItems
private Button button; private final CharSequence[] items = { "北京", "上海", " ...