本文描述了识别一个接口是否真的是 RESTful 接口的基本方法。符合 REST 架构风格的接口,称为 RESTful 接口。本文不打算从架构风格的推导方面描述,而是从 HTTP 标准的方面描述。识别的方法同时也是指导实践的原则。

      一、是否使用了正确(合适)的方法

目前对于 HTTP 标准滥用较多的,就是方法。谈起 RESTful 接口的方法,很多资料告诉大家,说 GET、POST、PUT、DELETE,分别对应数据库操作的 SELECT、INSERT、UPDATE、DELETE。其实这种理解是不正确的。

     方法有两个性质:安全性与幂等性;以及一个语义:动作本身的意思。RESTful 接口为各种数据抽象为资源,对资源的操作,主要是依据方法的两个性质,其次才是语义。

    GET 方法的语义是获取资源,性质是安全、幂等。也就是说,对资源进行安全幂等的操作,应该用 GET 或 HEAD,当目的是获取资源时,选用 GET,目的是获取资源的元数据时,使用 HEAD。使用安全幂等的方法执行不安全或不幂等的操作,都是错误的。一个典型的例子是:

1  GET /book/357?op=delete

      这个例子的意图是删除 ID 为 357 的 book,DELETE 是不安全的操作,却使用了 GET 这个安全幂等的操作。这作法的副作用是可能被缓存,所有组件(包括搜索引擎)都认为它是安全的,从而可能不加任何限制地对它进行访问。

     POST 方法的语义是提交资源。“提交”本身就是一个比较抽象的动词,即它的语义是可以根据环境变化的,如果将它与 INSERT 对应起来,是以偏概全的。它的性质是不安全、不幂等。这意味着所有组件对它都不缓存,不重复发送请求。执行不安全、不幂等的操作,唯有选择 POST 方法(标准未规定的所有自定义方法,在性质上等同于 POST)。

一个不安全、不幂等的方法,可以执行安全、幂等的操作,前提是需要牺牲缓存等属性。比如提交一个很多参数的查询,可以使用 POST。

HTTP/1.1标准那么多年,HTML标准到5了,为什么HTML的 form 只有 GET 和 POST 两种 action ?为没有不把 PUT、DELETE、PATCH 等方法加进去?其实是有原因的。

首先,form 元素的提交表单的按钮是 submit,与 POST 的语义是等同的。

其次,当浏览器获得一个资源时,form 只是资源的一部分,不能表示整个资源,根据 PUT/DELETE/PATCH 的定义,它无法表示它们。

由于 POST 的性质与抽象的语义,在没有合适的方法时,都可以使用 POST 代替。因此,将 POST 等同于新增/插入的那些文章或教材,都在误导人。

篇幅有限,其它方法不说了,网上基于其它方法的文章基本正确的。

二、是否支使媒体协商

     媒体协商是指客户端和服务器对某种媒体类型的处理能力。一般情况下,客户端并不知道服务器能处理哪种媒体。浏览器就是典型代表,它在无先验知识的情况下,会进行媒体探测:

1 GET / HTTP/1.1
2
3 Host: example.com
4
5 Accept: text/html; q=1.0, image/*; q=0.8, */*; q=0.1

 

     这是告诉服务器,我能非常有效地处理 HTML 类型的资源,图片也是很有效的,其它的资源类型,我也能接受。于是服务器就优先按 HTML 返回资源,如果没有 HTML 或 Image,就返回服务器自身最合适的,如 application/json。

假设服务器仅支持 application/json,当客户端要求一个 application/xml 时,应当返回 415 Unsupported Media Type,并在正文中说明支持哪种媒体类型。

举个值得学习的案例,Github:https://api.github.com/ ,大家可以自己试试。

三、是否能够进行状态转移

    这一点非常重要,也是 REST 的本意,状态转移!HTTP 标准实现的 REST 中,连接(Link)是实现状态转移的重要组件(HTML 的超链接和表单也是)。

在无先验知识的前提下,客户端请求资源 / ,这个资源及其元数据,要能够为应用程序的下一个状态的转移提供必要的连接。有时候甚至要提供文档说明的连接。

例如,当我们访问 https://api.github.com/ 时,我们看到一个连接的列表。通过这些连接,我们的客户端就可以跳转到另一个状态,从而实现整个应用程序的状态转移。状态如何更好的转移(甚至是自动化的状态转移),就要依赖于连接的关系(rel)以及连接的媒体类型(type)和可选的文档。

    这种状态转移的能力,正是 REST 的魅力。诚然,最成功的 REST 客户端是浏览器,最成功的媒体类型是 text/html,最成功的 REST 是 HTTP,通过 URI 标准构建的连接,进化成我们今天无法量化的巨大的分布式系统:Web。

   额外一点,一个 RESTful 的接口是不需在路径或头部字段中使用接口的版本号的。RESTful 接口这种说法,也有误。REST有统一接口的概念,但这个概念一般是指 HTTP 标准。在一个 RESTful 的环境中,一切事物都是资源,资源是没有版本号的。版本号是 API 的概念,API 是 RPC 的事物。

资源一旦发布,其结构就基本上不再发生变化。唯一能够变化的资源结构是在对旧资源无副作用的前提下,新增资源的字段或属性。当新增或删除的属性与当前资源的结构不兼容时,则需要增加一个或一类新的资源。因此,在 RESTful 实践中,是不需要使用版本号来标识资源的。

    当然,RESTful 内容的丰富,远远不止以上所提到的三点。但这三点是非常基本的要求。

    文章来自:http://my.oschina.net/heiing/blog/418882

[转]简单识别 RESTful 接口的更多相关文章

  1. SpringBoot IntelliJ创建简单的Restful接口

    使用SpringBoot快速建服务,和NodeJS使用express几乎一模一样,主要分为以下: 1.添加和安装依赖  2.添加路由(即接口) 3.对路由事件进行处理 同样坑的地方就是,祖国的防火墙太 ...

  2. RESTful接口设计原则/最佳实践(学习笔记)

    RESTful接口设计原则/最佳实践(学习笔记) 原文地址:http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api 1 ...

  3. Swagger+Spring mvc生成Restful接口文档

    简介 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集 ...

  4. 云脉推出表格识别API接口可以自助接入

    针对如今市场上对于海量票据信息的录入需求,近期厦门云脉技术有限公司推出票据识别相关的产品与服务,更是在云脉OCR SDK开发者平台上上线表格识别API接口,供广大开发者和集成商自助接入.为了降低财务系 ...

  5. 网络协议 21 - RPC 协议(中)- 基于 JSON 的 RESTful 接口协议

        上一节我们了解了基于 XML 的 SOAP 协议,SOAP 的 S 是啥意思来着?是 Simple,但是好像一点儿都不简单啊! 传输协议问题     对于 SOAP 来讲,比如我创建一个订单, ...

  6. python 全栈开发,Day100(restful 接口,DRF组件,DRF跨域(cors组件))

    昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确.方便快速开发 - 针对pc,手机,ipad,微信,支付宝... 使用同一个接口 2. 简述http协议? - 基 ...

  7. 使用webpy创建一个简单的restful风格的webservice应用

    下载:wget http://webpy.org/static/web.py-0.38.tar.gz解压并进入web.py-0.38文件夹安装:easy_install web.py 这是一个如何使用 ...

  8. vue项目构建实战基础知识:SPA理解/RESTful接口介绍/static目录配置/axios封装/打包时map文件去除

    一.SPA 不是指水疗.是 single page web application 的缩写.中文翻译为 单页应用程序 或 单页Web应用,更多解释请自行搜索. 所有的前端人员都应该明白我们的页面的 u ...

  9. RESTful 接口实现简明指南

    REST 简介 REST 是一个术语的缩写,REpresentational State Transfer,中文直译「表征状态转移」,这是个很拗口的词.我的建议是先不要强行理解,直接看怎么做,等对实施 ...

随机推荐

  1. C#操作XML小结(转)

    一.简单介绍 using System.Xml; //初始化一个xml实例 XmlDocument xml=new XmlDocument(); //导入指定xml文件 xml.Load(path); ...

  2. cocos2d-x之xml文件读取初试

    auto doc=new tinyxml2::XMLDocument(); doc->Parse(FileUtils::getInstance()->getStringFromFile(& ...

  3. 微信公众平台应用开发:方法、技巧与案例--柳峰,Java语言版本

    他本人的博客:http://blog.csdn.net/lyq8479 作者简介: 刘运强,网名“柳峰”,资深微信公众平台应用开发工程师,国内微信公众平台应用开发的先驱之一,项目经验丰富.他还是一位资 ...

  4. 生成大小为100的数组,从1到100,随机插入,不连续,也不重复[C#]

    生成大小为100的数组,从1到100,随机插入,不连续,也不重复. 实现思路 生成一个100位的集合listA,放1到100 创建一个空的集合listB,用来存放结果 创建一个变量c,临时存储生成的数 ...

  5. linux 删除已输入的命令行

    ctrl + w —往前删除一个单词,光标放在最末尾ctrl + k —删除到末尾,光标放在最前面(可以使用ctrl+a) —————————————————————-华丽的分割线ctl + u 删除 ...

  6. selenium处理div生成弹框

    目前遇到的弹框有两种,一种是alert,一种是div,如果遇到div模拟的弹框,在用alert就不行了. 1. public static Alert getAlert(WebDriver dr) { ...

  7. Debian安装中文输入法

    简单暴力: apt-get install ibus-pinyin 你也可以通过GUI下面到Synaptic Package Manager里面选中ibus-pinyin进行安装 安装完成后重启计算机 ...

  8. HDU 4409 Family Name List --乱搞、LCA

    题意: 给出一些名字,名字间有父子关系,有三种操作: 1.按祖先到后代,兄弟间按字典序由小到大排序,然后输出 2.求某个节点的兄弟节点有多少个,包括自己(注意,根节点的兄弟节点是1) 3.求节点a和b ...

  9. Java语法基础(一)----关键字、标识符、常量、变量

    一.关键字: 关键字:被Java语言赋予特定含义的单词.组成关键字的字母全部小写.注:goto和const作为保留字存在,目前并不使用.main并不是关键字. 二.标识符: 标识符:就是给类,接口,方 ...

  10. AC日记——舒适的路线 codevs 1001 (并查集+乱搞)

    1001 舒适的路线 2006年  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description Z小镇是 ...