RESTful相关信息整理

参考:可以看的出来我是阮一峰的忠实读者

  1. 阮一峰的《理解RESTful架构》 https://www.ruanyifeng.com/blog/2011/09/restful.html
  2. https://restfulapi.cn/
  3. 阮一峰的《RESTful API 设计指南》http://www.ruanyifeng.com/blog/2014/05/restful_api.html

起源

https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

  • Roy Thomas Fielding在2000年的时候发表的《Architectural Styles and the Design of Network-based Software Architectures》

  • 论文的目的

    "本文研究计算机科学两大前沿----软件和网络----的交叉点。长期以来,软件研究主要关注软件设计的分类、设计方法的演化,很少客观地评估不同的设计选择对系统行为的影响。而相反地,网络研究主要关注系统之间通信行为的细节、如何改进特定通信机制的表现,常常忽视了一个事实,那就是改变应用程序的互动风格比改变互动协议,对整体表现有更大的影响。我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。"
    
    (This dissertation explores a junction on the frontiers of two research disciplines in computer science: software and networking. Software research has long been concerned with the categorization of software designs and the development of design methodologies, but has rarely been able to objectively evaluate the impact of various design choices on system behavior. Networking research, in contrast, is focused on the details of generic communication behavior between systems and improving the performance of particular communication techniques, often ignoring the fact that changing the interaction style of an application can have more impact on performance than the communication protocols used for that interaction. My work is motivated by the desire to understand and evaluate the architectural design of network-based application software through principled use of architectural constraints, thereby obtaining the functional, performance, and social properties desired of an architecture. )

什么是RESTful

  • REST:Representational State Transfer,翻译过来就是表现层状态转化
  • 如果一个架构符合REST原则,就称它为RESTful架构。

资源 resource

  • REST的名称"表现层状态转化"中,省略了主语。"表现层"其实指的是"资源"(Resources)的"表现层"
  • 所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息
  • 它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在
  • 你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI
  • URI就成了每一个资源的地址或独一无二的识别符
  • 所谓"上网",就是与互联网上一系列的"资源"互动,调用它的URI

表现 Representation

  • 上面说了,资源的表现可以是:一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在
  • URI只代表资源的实体,不代表它的形式
  • 它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定,这两个字段才是对"表现层"的描述

状态转换 State Transfer

  • 访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。
  • 互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端
  • 如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)
  • 而这种转化是建立在表现层之上的,所以就是"表现层状态转化"
  • 客户端用到的手段,只能是HTTP协议
  • HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE(其实还有PATCH等)
  • 它们分别对应几种基本操作:
    • GET用来获取资源
    • POST用来新建资源(也可以用于更新资源)
    • PUT用来更新资源
    • PATCH: 更新(Update),通常是部分更新
    • DELETE用来删除资源

RESTful实例

  • RESTful 架构可以充分的利用 HTTP 协议的各种功能,是 HTTP 协议的最佳实践
  • RESTful API 是一种软件架构风格、设计风格,可以让软件更加清晰,更简洁,更有层次,可维护性更好

API请求设计

  • 请求 = 动词 + 宾语

  • 动词 使用五种 HTTP 方法,对应 CRUD 操作

  • 宾语 URL 应该全部使用名词复数,可以有例外,比如搜索可以使用更加直观的 search

  • 过滤信息(Filtering) 如果记录数量很多,API应该提供参数,过滤返回结果。 ?limit=10 指定返回记录的数量 ?offset=10 指定返回记录的开始位置。还有很多

    ?limit=10:指定返回记录的数量
    ?offset=10:指定返回记录的开始位置。
    ?page=2&per_page=100:指定第几页,以及每页的记录数。
    ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
    ?animal_type_id=1:指定筛选条件
请求 URI 作用
GET /zoos 列出所有动物园
POST /zoos 新建一个动物园
GET /zoos/ 获取某个指定动物园的信息
PUT /zoos/ 更新某个指定动物园的全部信息
PATCH /zoos/ 更新某个指定动物园的部分信息
DELETE /zoos/ 删除某个动物园
GET /zoos/{id}/animals 列出某个指定动物园的所有动物
DELETE /zoos/{id}/animals/ 删除某个指定动物园的指定动物

API响应设计

  • 客户端的每一次请求,服务器都必须给出回应。回应包括 HTTP 状态码和数据两部分。
  • 五大类状态码,总共100多种,覆盖了绝大部分可能遇到的情况。每一种状态码都有约定的解释,客户端只需查看状态码,就可以判断出发生了什么情况。API 不需要1xx状态码
    • 1xx 相关信息
    • 2xx 操作成功
    • 3xx 重定向
    • 4xx 客户端错误
    • 5xx 服务器错误

服务器回应数据

  • 客户端请求时,要明确告诉服务器,接受 JSON 格式,请求的 HTTP 头的 ACCEPT 属性要设成 application/json
  • 服务端返回的数据,不应该是纯文本,而应该是一个 JSON 对象。服务器回应的 HTTP 头的 Content-Type 属性要设为 application/json
  • 错误处理 如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将 error 作为键名,出错信息作为键值即可。
  • 认证 RESTful API 应该是无状态,每个请求应该带有一些认证凭证。推荐使用 JWT 认证,并且使用 SSL
  • Hypermedia 即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么

误区

URI包含动词

  • 因为"资源"表示一种实体,所以应该是名词,URI不应该有动词,动词应该放在HTTP协议中

  • 错误的示例

    POST /accounts/1/transfer/500/to/2
  • 正确的做法:把动词transfer改成名词transaction,资源不能是动词,但是可以是一种服务

    POST /transaction HTTP/1.1
    Host: 127.0.0.1
      
    from=1&to=2&amount=500.00

在URI中加入版本号

  • 错误的示例

    http://www.example.com/app/1.0/foo
  • 正确的做法:因为不同的版本,可以理解成同一种资源的不同表现形式,所以应该采用同一个URI。版本号可以在HTTP请求头信息的Accept字段中进行区分

    参考 https://www.informit.com/articles/article.aspx?p=1566460

    Accept: vnd.example-com.foo+json; version=1.0

最新文章

  1. A ship is always safe at the shore - but that is not what it is built for.
  2. 【BZOJ】1087: [SCOI2005]互不侵犯King(状压dp)
  3. test generation和MBIST
  4. Codeforces Round #133 (Div. 2)
  5. php魔法常量
  6. Performing Post-Build Event之类的编译错误
  7. [条款36]绝不重新定义继承而来的non-virtual函数
  8. Hibernate三大类查询总结
  9. 小说接入UC浏览器内核技术对话(二)
  10. python 视频转成代码视频
  11. ubuntu“少折腾”
  12. centos 7 linux系统安装 mysql5.7.17(glibc版)
  13. 关于lower_bound( )和upper_bound( )的常见用法
  14. 13. Redis监控运维云平台CacheCloud
  15. tomcat和jdk版本兼容(Tomcat版本要比jdk高)
  16. HTML文本元素标签
  17. 开源的CAS实现SSO
  18. Android RelativeLayout属性介绍
  19. HBase Compaction详解
  20. 51Nod 1081:子段求和(前缀和)

热门文章

  1. fastposter v2.10.0 简单易用的海报生成器
  2. Java安全之Mojarra JSF反序列化
  3. perl chmod
  4. docker使用bind9实现域名解析
  5. Halo 主题 Redemption 首发版
  6. 【Java EE】Day09 JavaScript基础
  7. gulp报错The following tasks did not complete
  8. Blazor 部署 pdf.js 不能正确显示中文资源解决办法
  9. Window系统的mysql数据库定时备份
  10. UBOOT 启动流程