Rest api简介
理解和使用内容协商
我们的开发者在发送一个 REST API 请求的同时,根据应用场景,针对相同的资源,可能会期待不同的返回形式。
比如,我希望根据用户客户端语言,同一个资源的内容可以返回不同的语言。又比如,当我使用 Java 编程的时候,我希望得到 ATOM 格式的返回结果,而当我使用 JavaScript 编程的时候,我希望得到 Json 格式的返回结果。
因此,我们在设计 REST API 的时候,应该提供完备的内容协商能力。
使用 URL 参数进行内容协商
最容易想到的自然是通过 URL 参数进行控制,我们经常看到形如 / 航班号 /entry? format=JSON 这样的 URL。这种方式的优势就是简单灵活, 你可以通过任何 URL 参数来组合你的输出格式。
下面是一个来自 IBM developerWorks 的 API 样例,尝试请求该 API,你可以看到该集合是如何支持不同的输出格式请求的。
清单 3. IBM developerWorks 的文件服务标签云的 API
REST API 请求,要求返回 XML 格式数据: GET https://www.ibm.com/developerworks/mydeveloperworks /files/form/anonymous/api/tags/feed?format=xml &scope=document&pageSize=30&sK=cloud&sO=dsc REST API 请求,要求返回 JSON 格式数据: GET https://www.ibm.com/developerworks/mydeveloperworks /files/form/anonymous/api/tags/feed?format=json &scope=document&pageSize=30&sK=cloud&sO=dsc
使用 Accept 头进行内容协商
使用 URL 参数,简单灵活,但是也由此带来了设计上的随意和不标准。并且,过多的参数会导致 URL 的可读性变差,更有甚者,可能会导致 URL 过长,超出规范,API 请求无法执行。
更为标准的内容协商方式是使用 HTTP 头。我们通常使用 Accept 来设置我们接受的返回结果的内容格式,用 Accept-Charset 来设置字符集,用 Accept-Encoding 来设置数据传输格式,用 Accept-Language 来设置语言。
使用 URI 模式进行内容协商
还有一种模式,就是将协商设置直接作为 URI 的一部分,将不同的返回视为不同的资源,比如 / 航班号 /json 来返回 JSON 格式的结果,用 / 航班号 /atom 来返回 ATOM 格式的结果。
正确的使用 HTTP 响应代码
作为 API 的设计者,正确的将 API 执行结果和失败原因用清晰简洁的方式传达给客户程序是十分关键的一步。 我们确实可以在 HTTP 的相应内容中描述是否成功,如果出错是因为什么, 然而, 这就意味着用户需要进行内容解析,才知道执行结果和错误原因。因此,HTTP 响应代码可以保证客户端在第一时间用最高效的方式获知 API 运行结果,并采取相应动作。 下表列出了比较常用的响应代码。
表 1. 常用 HTTP 响应代码含义
| HTTP 响应代码 | 代码含义 |
|---|---|
| 200 | 已创建,请求成功且服务器已创建了新的资源。 |
| 201 | 是否只显示处于警告状态的应用实例 |
| 301 | 重定向 , 请求的网页已被永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。 |
| 302 | 重定向 , 请求的网页临时移动到新位置,但求者应继续使用原有位置来进行以后的请求。302 会自动将请求者转到不同的临时位置。 |
| 304 | 未修改,自从上次请求后,请求的网页未被修改过。服务器返回此响应时,不会返回网页内容。 |
| 400 | 错误请求 , 服务器不理解请求的语法。 |
| 401 | 未授权 , 请求要求进行身份验证。 |
| 403 | 已禁止 , 服务器拒绝请求。 |
| 404 | 未找到 , 服务器找不到请求的网页。 |
| 405 | 方法禁用 , 禁用请求中所指定的方法。 |
| 406 | 不接受 , 无法使用请求的内容特性来响应请求的网页。 |
| 408 | 请求超时 , 服务器等候请求时超时。 |
| 410 | 已删除 , 如果请求的资源已被永久删除,那么,服务器会返回此响应。 |
| 412 | 未满足前提条件 , 服务器未满足请求者在请求中设置的其中一个前提条件。 |
| 415 | 不支持的媒体类型 , 请求的格式不受请求页面的支持。 |
| 500 | 内部服务器错误。 |
使用 HTTP 头处理缓存和并发
缓存和并发处理,从来是大型软件系统设计中的重要组成部分。
使用 HTTP 头进行缓存处理
在 REST 的构架中,我们除了在与后台的数据交换中,需要有一个良好的缓存机制外,针对 REST API 请求都是在远端用 HTTP 发起这一特点,还需要为网络缓存进行更多考虑。通过减少 HTTP 响应内容,避免不必要的 HTTP 连接等方式,达到提高 REST API 使用效率的目的。
HTTP 头中,有多个字段可以用于缓存处理。比较常用的有缓存控制和条件请求。
缓存控制:
缓存控制通常是需要客户端,缓存服务器 / 代理服务器与业务服务器一起发生作用。
HTTP 头中有“Cache-control”字段来控制如何使用缓存,常见的取值有 private、no-cache、max-age、must-revalidate 等。比如当你给返回的数据内容设置 max-age=600,那么当用户隔了 30 秒再次请求的时候,就不会导致重新请求后台数据。
另外,也可以通过“Expires”字段来指定内容过期时间,在此时间前的请求都不会导致后台程序重新请求数据。
下图展示了 max-age 是如何工作的。
图 2. 缓存控制工作方式的简单范例
条件请求与电子标签:
很多时候,数据内容可能会几个小时甚至几天都不会发生变动,这个时候根据请求时间间隔来控制缓存,就不能满足系统的需求了。通过支持条件请求与电子标签,可以帮助我们来解决这个问题。
当用户请求数据内容时,系统在返回数据的同时,在 HTTP 头中,将返回根据服务器内容的最后修改时间 Last-Modified,或者根据服务器内容生成电子标签 ETag。 当用户再次请求数据时,就可以在 HTTP 请求中使用 If-Modified-Since 或者 If-None-Match 头信息,把上次请求得到的时间戳或者电子标签传给服务器。当收到一个有条件请求的 HTTP 头的 REST 请求的时候,我们的程序需要将收到的时间戳或者电子标签与当前内容作比较,就可以很容易的知道用户请求的数据内容在这段时间是否发生过修改,并根据比较结果返回给用户最新内容,或者用 HTTP 响应码 304 告知用户,内容没有变化。
下面是一个来自 IBM developerWorks 的 API 样例,尝试请求该 API,你可以看到该 API 会在 HTTP 头中返回电子标签和缓存处理信息。
清单 4. IBM developerWorks 的带有电子标签的文件服务 API
REST API 请求: GET https://www.ibm.com/developerworks/mydeveloperworks /form/anonymous/api/communitylibrary /7e2e8015-bf72-43b6-bacd-36565b67febc/document /ddc0ef4e-224e-449c-bb2c-f919fafb17d2 /entry?acls=true&includeRecommendation=true &includeTags=false&includeLibraryInfo=true&format=xml
使用 HTTP 头进行并发处理
上文我们提到了使用条件请求控制缓存,其实我们还可以使用条件请求进行并发处理。
比如当用户 Alice 和 Bob 通过 REST 获取了一篇文档。Bob 阅读文档之后,通过 PUT 来修改文档;而此前几分钟,Alice 刚刚修改了这篇文档,于是 Bob 就在毫不知情的情况下不慎覆盖了 Alice 的修改。
通过在写操作中支持条件请求,我们可以更好的处理并发修改。用户在发出修改请求的同时,在 HTTP 请求中使用 If-Not-Modified-Since 或者 If-Match 头信息,把获取数据时得到的时间戳或者电子标签传给服务器;我们的程序通过与服务器当前内容的比较,就可以知道,这个修改请求是否是针对当前内容提出的。当服务器发现内容已经被其他用户修改过了,就不会执行修改请求,并返回 HTTP 响应码 412(未满足前提条件)给用户。
下图展示了使用条件请求和电子标签进行并发处理是如何工作的
图 3. 支持条件请求时的并发处理简单范例
更好的使用数据冗余和链接元素
在 ATOM 文档中,我们用各种数据元素来传递信息。其中有一类元素叫做链接,可以用于开发者的进一步访问。通常,我们会提供编辑当前资源的链接,访问当前资源的链接,等等。通过更加灵活的使用这类链接元素,以及提供必要的数据冗余,我们可以大大简化开发者的编程逻辑,提高 REST API 的使用效率
更多的需要注意的细节与技巧
除了以上提到的方面,还有大量的细节与技巧,可以帮助我们更好的设计 REST API:
批量更新:
当用户需要更新多个资源的时候,你打算让开发者一次次的发送 HTTP 请求逐个更新吗?你可以考虑在设计 API 的时候允许客户同时创建或者更新多个资源。
REST 安全:
除了使用固有的 HTTP 基本验证,你还可以考虑通过支持表单验证,LTPA 验证,Open ID 验证等方式,来满足更多的企业安全要求。
文档服务:
是否由于 API 持续更新,使得客户端连接不同版本服务的时候疲于奔命?尝试着把你的 API 定义规范成 XML 文档,这样客户端很容易理解当前服务可以提供哪些功能,以及如何使用这些功能。
你还可以通过阅读其他文档得到更多这方面的指导,本文无法将所有的细节与技巧一一穷尽。
Rest api简介的更多相关文章
- Web Api 简介
ASP.NET Web API 简介 ASP.NET MVC 4 包含了 ASP.NET Web API, 这是一个创建可以连接包括浏览器.移动设备等多种客户端的 Http 服务的新框架, ASP. ...
- ZooKeeper系列4:ZooKeeper API简介及编程
问题导读: 1.ZooKeeper API 共包含几个包? 2.如何使用ZooKeeper API 创建zookeeper应用程序? 1)ZooKeeper API 简介 ZooKeeper AP ...
- WebSocket API简介
WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,Safari,Firefox,Opera,IE等等,对该协议支持最早的应该是chrome,从chr ...
- 构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介
构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介 熟悉将用于 Apache Tuscany SCA for C++ 的 API.您将通过本文了解该 API 的主要组 ...
- Raphael Js矢量库API简介:
Raphael Js矢量库API简介:Raphael Javascript 是一个 Javascript的矢量库. 2010年6月15日,著名的JavaScript库ExtJS与触摸屏代码库项目jQT ...
- 开放数据接口 API 简介与使用场景、调用方法
此文章对开放数据接口 API 进行了功能介绍.使用场景介绍以及调用方法的说明,供用户在使用数据接口时参考之用. 在给大家分享的一系列软件开发视频课程中,以及在我们的社区微信群聊天中,都积极地鼓励大家开 ...
- Monkey脚本API简介
一.API简介 LaunchActivity(pkg_name, cl_name):启动应用的Activity.参数:包名和启动的Activity. Tap(x, y, tapDuration): 模 ...
- web API简介(四):客户端储存之IndexedDB API
概述 前篇:web API简介(三):客户端储存之Web Storage API 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据. Index ...
- web API简介(三):客户端储存之Web Storage API
概述 前篇:web API简介(二):客户端储存之document.cookie API 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据. W ...
- web API简介(二):客户端储存之document.cookie API
概述 前篇:web API简介(一):API,Ajax和Fetch 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据.document.cook ...
随机推荐
- hive 压缩全解读(hive表存储格式以及外部表直接加载压缩格式数据);HADOOP存储数据压缩方案对比(LZO,gz,ORC)
数据做压缩和解压缩会增加CPU的开销,但可以最大程度的减少文件所需的磁盘空间和网络I/O的开销,所以最好对那些I/O密集型的作业使用数据压缩,cpu密集型,使用压缩反而会降低性能. 而hive中间结果 ...
- activiti 配置节点 连线信息获取
1.1.1. 前言 当使用eclipse插件进行流程设计的时候,部署流程之后,我们如何获取我们定义的所有的节点.连线.关口等配置信息呢?有的人看到这个需求,不免窃喜,这不很简单嘛,重新打来bmpn中定 ...
- 在电脑上安装Linux操作系统
1硬件需求 A 一台电脑 B 一个优盘 2软件需求 A制作优盘启动盘的软件PowerISO BLinux操作系统的镜像文件 3安装PowerISO,并使用PowerISO A安装PowerISO B插 ...
- 乐观的并发策略——基于CAS的自旋
悲观者与乐观者的做事方式完全不一样,悲观者的人生观是一件事情我必须要百分之百完全控制才会去做,否则就认为这件事情一定会出问题:而乐观者的人生观则相反,凡事不管最终结果如何,他都会先尝试去做,大不了最后 ...
- 无网络环境下安装Dynamics CRM
在安装CRM时会需要很多的组件支持,没有这些组件是没法安装的,一般我们都是选择机器联网后在线安装,但也有特殊情况确实不能联网的,可参考这篇文章 https://blogs.msdn.microsoft ...
- Android获得控件在屏幕中的绝对坐标
int[] location = new int[2] ; view.getLocationInWindow(location); //获取在当前窗口内的绝对坐标 view.getLocationOn ...
- UNIX网络编程——tcp流协议产生的粘包问题和解决方案
我们在前面曾经说过,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体 ...
- JSP自定义简单标签入门之带有属性
上面写的那个简单标签来控制页面中标签内容的重复次数是固定的,这就是权限"写死了",这是非常不好的行为,因为其灵活性太差.所以下面就介绍一种使用属性来控制标签内容输出次数的方法. 准 ...
- 精通CSS+DIV网页样式与布局--页面和浏览器元素
在页面和浏览器中,除了文字.图片.表格.表单等,还有很多各种各样的元素,在上篇博文中,小编主要简单的介绍了一下在CSS中如何设置表格和表单,今天小编主要简单介绍一下丰富的超链接特效.鼠标特效.页面滚动 ...
- 精通CSS+DIV网页样式与布局--页面背景
上篇博客,我们主要简单的总结了CSS的图片效果,我们这回来讲讲CSS如何对网页的背景进行设置,网页的背景是整个网页的重要组成部分,她直接决定了整个网页的风格和色调.这篇博客简单的总结一下如何用CSS来 ...