在网上找了许久的关于REST的资料,发现网上大部分都是说的比较片面,虽然有部分说出了本质,但也没有详细提出,所以在这里记录一下。

RESTful是什么

首先,维基百科是这样说的:

表现层状态转换(REST,英文:Representational State Transfer)是Roy Thomas Fielding博士于2000年在他的博士论文中提出来的一种万维网软件架构风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息

这样的概念有点难以理解,了解一个东西,通常可以先了解他的背景,他是为了解决什么问题而出现的?

Fielding是一个非常重要的人,他是HTTP协议(1.0版和1.1版)的主要设计者、Apache服务器软件的作者之一、Apache基金会的第一任主席。

而下面则是他在论文中提出REST的目的。

"本文研究计算机科学两大前沿----软件和网络----的交叉点。
长期以来,软件研究主要关注软件设计的分类、设计方法的演化,很少客观地评估不同的设计选择对系统行为的影响。
而相反地,网络研究主要关注系统之间通信行为的细节、如何改进特定通信机制的表现,常常忽视了一个事实,那就是改变应用程序的互动风格比改变互动协议,对整体表现有更大的影响。
我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。"

这段话比较绕口,总结一下,就是REST是一个为了进一步解耦client和server的架构风格。

首先,根据论文可以得知,REST风格是由约束来定义的

Web 架构背后的设计基本原理,能够被描述为由一组应用于架构中元素之上的约束组成
的架构风格。当将每个约束添加到进化中的风格时,会产生一些影响。通过检查这些影响,
我们就能够识别出 Web 的约束所导致的属性。然后就能够应用额外的约束来形成一种新的
架构风格,这种风格能够更好地反映出现代 Web 架构所期待的属性。
  1. client-servet
     client-server之间的解耦,服务提供者和服务消费者互不影响,也是我们常说的前后端分离。
    前后端分离的优势是比较显著的,改善了用户接口跨多个平台的可移植性;同时通过简化服务器组件,改善了系统的可伸缩性。
  2. 无状态
    这个约束使架构拥有了可见性、可靠性和可伸缩性等三个架构属性。
    可见性是指能单独的理解一个请求,可靠性是减轻了从局部故障中恢复的任务量, 可伸缩性是指为不必在多个请求之间保 存状态,从而允许服务器组件迅速释放资源
  3. 可缓存。
    优势明显,不赘述。
  4. 统一接口
    它强调组件之间要有 一个统一的接口。通过在组件接口上应用通用性的软件工程原则,整体的系统架 构得到了简化,交互的可见性(通过方法名即知道动作)也得到了改善。实现与它们所提供的服务是解耦的,这促进了独立的可进化性。
    然而,付出的代价是,统一接口降低了效率,因为信息都使用标准化的形 式来转移,而不能使用特定于应用的需求的形式。(只能使用put post delete get patch等)
    解决方法:为需要的动作增加一个 endpoint,使用 POST 来执行动作,比如 POST /resend 重新发送邮件。
  5. 分层系统
    分层系统风格通过限制组件的行为(即,每个组件只 能“看到”与其交互的紧邻层),将架构分解为若干等级的层。通过将组件对系统的知识限 制在单一层内,为整个系统的复杂性设置了边界,并且提高了底层独立性。
    我们能够使用层 来封装遗留的服务,使新的服务免受遗留客户端的影响,通过将不常用的功能转移到一个共 享的中间组件中,从而简化组件的实现。中间组件还能够通过支持跨多个网络和处理器的负 载均衡,来改善系统的可伸缩性。
    也就是说服务器和客户端之间的中间层(代理,网关等)代替服务器对客户端的请求进行回应,而客户端不需要关心与它交互的组件之外的事情
  6. 按需加载代码
    通 过下载并执行 applet 形式或脚本形式的代码,REST允许对客户端的功能进行扩展。通过减少必须被预先实现的功能的数目,简化了客户端的开发。允许在部署之后下载功能代 码也改善了系统的可扩展性。然而,这也降低了可见性,因此它只是 REST的一个可选的约 束。

了解了REST是什么东西后,我们才能设计出合适的API,以下是根据GITHUB API来总结的(基本参考自:https://cizixs.com/2016/12/12/restful-api-design-guide/)

设计原则(GITHUB API):

  1. 使用https
    这个和 Restful API 本身没有很大的关系,但是对于增加网站的安全是非常重要的。
  2. API地址和版本
    如果 API 变化比较大,可以把 API 设计为子域名,比如 https://api.github.com/v3

  3. 响应内容
    尽量使用JSON,JSON在多种语言中支持,如果需要使用其他的如XML, 应该在请求头部 Accept 中指定
  4. 以资源为中心
    资源分为单个文档和集合,尽量使用复数来表示资源,单个资源通过添加 id 或者 name 等来表示
    一个资源可以有多个不同的 URL
    资源可以嵌套,通过类似目录路径的方式来表示,以体现它们之间的关系 
    /users/:username/repos
    /users/:org/repos
    /repos/:owner/:repo
    /repos/:owner/:repo/tags
    /repos/:owner/:repo/branches/:branch
  5. 使用正确的METHOD
    这个比较容易理解,即get(获取),post(创建),put(替换),patch(局部更新),delete(删除),head(获取某个资源的头部信息。比如只想了解某个文件的大小,某个资源的修改日期等)
  6. 对于不符合CURD的情况,可以采用参数协助
    如分页page=2&per_page=100:指定第几页,以及每页的记录数, 或者增加一个endpoint,如上面说的重发邮件,或者将动作转换为资源(Github:比如“喜欢”一个 gist,就增加一个 /gists/:id/star 子资源,然后对其进行操作:“喜欢”使用 PUT /gists/:id/star,“取消喜欢”使用 DELETE /gists/:id/star
  7. 状态码,https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
    • 2XX:请求正常处理并返回
    • 3XX:重定向,请求的资源位置发生变化
    • 4XX:客户端发送的请求有错误
    • 5XX:服务器端错误
  8. 错误处理
    返回错误时,在响应内容里加上具体的错误信息。
  9. Hypermedia API
    当服务端修改API时,客户端不需要知道和修改。
  10. 验证和授权, OAUTH2等
  11. 限流, 参考github,https://developer.github.com/v3/rate_limit/

    对用户的请求限流之后,要有方法告诉用户它的请求使用情况,Github API 使用的三个相关的头部:

    X-RateLimit-Limit: 用户每个小时允许发送请求的最大值
    X-RateLimit-Remaining:当前时间窗口剩下的可用请求数目
    X-RateLimit-Rest: 时间窗口重置的时候,到这个时间点可用的请求数量就会变成 X-RateLimit-Limit 的值

  12. 编写清晰的文档

  

REST与http的关系?

个人理解是REST是一种架构风格,而http则是这种架构实现下的一种协议。

比较(以操作为中心):

  1. 以操作为中心可见性低,即不够清晰。
  2. 在除了CURD的接口外,以操作为中心调用效率高,不需要hack。
  3. 以操作为中心没有HyperMidea Api,修改api效率低,需要客户端服务端同时修改。
  4. 以操作为中心上手难度系数大。
  5. 以资源为中心,简单数据操作,无事务处理,开发和调用简单, 以操作为中心,清晰的规范标准定义,能够处理较为复杂的面向活动的服务
    在通常的软件开发过程中,我们常常需要分析达成某个目标所需要使用的业务逻辑,并为业务逻辑的执行提供一系列运行接口。在一些Web服务中,这些接口常常表达了某个动作,如将商品放入购物车,提交订单等。这一系列动作组合在一起就可以组成完成目标所需要执行的业务逻辑。在需要调用这些接口的时候,软件开发人员需要向这些接口所在的URL发送一个请求,从而驱使服务执行该动作

以基金交易为例子

RESTful杂记的更多相关文章

  1. Restful API设计规范及实战【说的比较清楚了】

    Restful API设计规范及实战   Restful API的概念在此就不费口舌了,博友们网上查哈定义文章很多,直入正题吧: 首先抛出一个问题:判断id为 用户下,名称为 使命召唤14(COD14 ...

  2. Restful资源文章

    理解RESTful架构 RESTful API设计指南 RESTful架构详解 NodeJs的RESTful API

  3. 【接口开发】浅谈 SOAP Webserver 与 Restful Webserver 区别

    接口,强大,简单,交互,跨越平台 下面简单阐述这两大接口思想 一 REST: REST是一种架构风格,其核心是面向资源,REST专门针对网络应用设计和开发方式,以降低开发的复杂性,提高系统的可伸缩性. ...

  4. (转载) RESTful API 设计指南

    作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...

  5. angular中使用ngResource模块构建RESTful架构

    ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入 ...

  6. Linux学习日记-WCF RestFul的部署(三)

    一.关于WCF 的部署 默认的wshttp风格的wcf是很容易部署上去的,但是这里给个建议尽量不要使用WCF的配置文件去部署尽管 我们都已经很熟悉了,在使用配置文件你会发现各种蛋疼的问题. 二.WCF ...

  7. Node.js实现RESTful api,express or koa?

    文章导读: 一.what's RESTful API 二.Express RESTful API 三.KOA RESTful API 四.express还是koa? 五.参考资料 一.what's R ...

  8. Restful WebApi项目开发实践

    前言 踩过了一段时间的坑,现总结一下,与大家分享,愿与大家一起讨论. Restful WebApi特点 WebApi相较于Asp.Net MVC/WebForm开发的特点就是前后端完全分离,后端使用W ...

  9. Java——搭建自己的RESTful API服务器(SpringBoot、Groovy)

    这又是一篇JavaWeb相关的博客,内容涉及: SpringBoot:微框架,提供快速构建服务的功能 SpringMVC:Struts的替代者 MyBatis:数据库操作库 Groovy:能与Java ...

随机推荐

  1. 数据安全存放,全民搭建kodexplorer私有云存储

    数据安全存放可以说越来的重要,新闻上也经常报道出关于个人信息泄露的事件,不仅泄露,还有一些进行个人隐私买卖,之前报道出facebook便是如此.数字信息存放好比存钱一样,存在别人那里总会不放心.不如自 ...

  2. js 面向对象的三大特性:封装,继承、多态

    一:什么是封装? 封装的定义:就是对象内部的变化对外界是透明的,不可见的. 封装的场景: 在写项目的过程中,有时候不同页面,会有相同的功能,我们还需要每个页面都写一遍吗?额,,,,其实也可以写的,只不 ...

  3. 33 ArcToolBox学习系列之数据管理工具箱——投影与变换(Projections and Transformations)未完待续……

    工具箱位置 打开ArcToolBox,找到工具集Projections and Transformations,位置如下:ArcToolbox--Data Management Tools--Proj ...

  4. Red and Black---POJ - 1979

    There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A ...

  5. java points[复习]

    1 - & 与 && 的区别: &:不管左边是true还是false,右端都会进行运算: &&:当左端为false时,右端不再进行运算: 即在与运算时, ...

  6. 2019PHP面试题最全面归纳总结

    1.请选择以下代码运行的结果: <?php if ('1e3' == '1000') echo 'LOL'; ?> A 无任何输出结果  B   LOL  C 不执行且报错 解析:1e3 ...

  7. unittest批量执行测试用例

    现有四个测试用例分别在两个.py文件中,如何执行这些文件? unittest中有这样处理:unittest.TestLoader().discover() 第一个文件test_case1.py fro ...

  8. Hadoop 集群安装(从节点安装配置)

    1.Java环境配置 view plain copy sudo mv /tmp/java /opt/ jdk安装完配置环境变量,编辑/etc/profile: view plain copy sudo ...

  9. python预编译函数compile,exec,eval

    funcname = "func" func = "def %s():\n" % funcname funccontent = 'print "hel ...

  10. Netty(一) SpringBoot 整合长连接心跳机制

    前言 Netty 是一个高性能的 NIO 网络框架,本文基于 SpringBoot 以常见的心跳机制来认识 Netty. 最终能达到的效果: 客户端每隔 N 秒检测是否需要发送心跳. 服务端也每隔 N ...