参考文章

  • 特点:没有后缀
  • 表述性状态传递,一种命名规范。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格式的首部,紧接着是两个空行,然后是响应包体。