参考文章
- 特点:没有后缀
- 表述性状态传递,一种命名规范。REST定义了web的使用标准,主要是http和url。
- 例如资源标识符url,能对无论图片,Word文档还是视频文件,甚至只是一种虚拟的服务,都可以通过url进行唯一标识。
- url决不包含动词,一定是对资源描述的抽象。
- 对资源使用一致的命名规则最主要的好处就是易于被其他人理解。
- 例子:
基本术语
- Resource(资源):单个实例对象,例如animal(一只动物);[逍遥子笔记:Roy ThomasFielding(REST风格的提出者)如此解释资源的含义:一个资源可以是一份文档、一张图片、一个与时间相关的服务(例如:洛杉矶今天的天气)等等,资源是实体的概念性映射,而不是实体本身;个人理解:一张图片是一个资源,但是在我本机中有一个的名字叫做“jason.txt”的、实实在在的文件实体,就不能称作资源,它是资源实体,简单而言:“资源”与“资源实体”之间犹如类和对象的关系。]
- Collection(集合):集合是一组同类的实例对象,例如animals(一群动物)。
- HTTP:一种在网络上传输的通信协议;
- Consumer(使用方、用户):能够发送http请求的客户端程序;[逍遥子笔记:这里Consumer实际是指API的调用方,如果直译成消费者更让人困惑]
- Third Party Developer(第三方开发人员):不是你项目项目团队的成员,但希望使用你的服务的那些开发人员;
- Server(服务器):能够被Consumer通过网络访问的HTTP服务器/程序;
- Endpoint(端点):服务器提供的一个URL,它标识了一个资源(Resource)或者集合(Collection);[逍遥子笔记:这里理解为URL最后面的那个字段更合适,例如URL: https://api.example.com/vi/zoos的端点就是:/zoos;]
- Idempotent(幂等):多次重复操作得到的结果一样;
- URL Segment(URL片段):从某个URL中取出的一小部分片段
HTTP动词
- GET(SELECT):从服务器获取一个指定资源或一个资源集合;
- POST(CREATE):在服务器上创建一个资源;
- PUT(UPDATE):更新服务器上的一个资源,需要提供整个资源;
- PATCH(UPDATE):更新服务器上的一个资源,只提供资源中改变的那部分属性;
- DELETE(DELETE):移除服务器上的一个资源;
为url增加版本号
- 在url中加入版本号是一个优秀的API设计。
- 例如下面一个通信项目IM包含很多级别的资源,那么版本号应该加在url哪里好呢?
- 资源树状图如下:
假设我的URL根(在本文后面将会介绍URL的根)为:https://test.jason.com/im/*,那么上述资源对应的URL为:
- (1)https://test.jason.com/im/user_info/public/self_info
该URL表示资源:用户个人简介的二维码信息;
- (2)https://test.jason.com/im/user_info/private/lock
该URL表示资源:用户的应用锁信息;
- (3)https://test.jason.com/im/user_rel/friends
该URL表示资源:用户的好友信息
- (4)https://test.jason.com/im/user_rel/groups/member
该URL表示资源:群组的群成员
- (5)https://test.jason.com/im/user_rel/groups/info
该URL表示资源:群组的信息
- (6)https://test.jason.com/im/message/new
该URL表示资源:用户新聊天消息
- (7)https://test.jason.com/im/message/history
该URL表示资源:用户的历史聊天消息
问题是:在这种情况下版本号应该放在URL的那个地方?
如果版本号是针对IM整个项目,例如这里的IM项目整体分为v1和v2两个大版本,此时的URL首部就能改成:https://test.jason.com/im/v1/,https://test.jason.com/im/v2/,实际的URL资源将变成:https://test.jason.com/im/v1/message/new。
如果版本号是针对IM项目中的某个子类,例如这里的message类型分为v1和v2两个版本,那么消息类的URL根就会变成:https://test.jason.com/im/message/v1/,https://test.jason.com/im/message/v2/,实际的URL资源将会变成:https://test.jason.com/im/message/v1/new。
为API增加计数器
- 为跟踪各版本的API被调用的情况,以便第三方开发人员及时优化API,可以通过在数据库中为每个API增加一个计数器来实现,来一个请求就将对应的使用计数加1,优化
API的根url
- API的根url应该尽量简单。
- 这里有两个普通的url根:
- https//example.org/api/vi/*
- https//example.com/vi/*
- 如果你的应用程序不会变得那么大,或者你想简化程序的使用,就把你的API放在url的根域(/api/)之后。
- 设计url时也应尽量把所表示的资源分层级。
- 最好让你的API的根也包含内容。例如,访问githubAPI的根就会得到一个端点(资源)列表。
端点
- 端点是url中用于标识一个特定资源或资源集合的那部分url片段。
- 例如,http://api.example.com/v1/zoos中的zoos。
- 假如你想构建用于表示多个动物园资源的API,其中,每个动物园都包含很多动物、雇员,并且需要跟踪每个动物的详细信息,那么这些API的端点可能如下所示:(最后即为端点)
- 在介绍这些端点的时候,你需要给出这些端点以及操作它们的HTTP动作。例如:
- GET /zoos:列出所有的动物园(包括动物园的ID、名称以及简介);
- POST /zoos: 创建一个新的动物园;
- GET /zoos/ZID:获取一个完整的动物园对象;[逍遥子笔记:这里的动物园对象仅仅指“动物园”,例如“动物园”的ID、名称、介绍等信息,而不包含该动物园中的动物、雇员等下辖类型的信息]
- PUT /zoos/ZID:更新一个动物对象(包含全部信息);
- PATCH /zoos/ZID:更新一个动物对象(包含部分信息);
- DELETE /zoos/ZID: 删除一个动物园对象;
- GET /zoos/ZID/animals:获取指定动物园的全部动物信息(包括动物的ID和名称);
- GET /animals:是指列出所有动物信息;
- POST /animals: 创建一个新的动物;
- GET /animals/AID: 获取某个动物的对象信息;
- PUT /animals/AID:更新一个动物的对象信息(提供对象的全部内容);
- PATCH /animals/AID:更新一个动物的对象信息(提供对象的部分内容);
- GET /animal_types: 获取所有的动物类型信息;
- GET /animal_types/ATID: 获取指定动物类型的类型描述信息;
- GET /employees:获取所有的雇员列表;
- GET /employees/EID:获取一个指定雇员的信息;
- GET /zoos/ZID/employees:获取指定动物园的全部雇员列表;
- POST /employees:创建一个新雇员;
- POST /zoos/ZID/employees:为指定动物园增加一个雇员;
- DELETE /zoos/ZID/employees/EID:解雇指定动物园的某个雇员;
HTTP包
- 请求包:当用户发送一个HTTP请求到服务器时,在请求包里提供了一个key/value集合,叫做HTTP首部,紧随其后的是两个空行(一个回车符一个换行符),最后是请求包体。
- 响应包:服务器对请求的响应也是以key/valu格式的首部,紧接着是两个空行,然后是响应包体。