REST 概念来源

  网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备...)。 因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信。这导致 API 构架的流行,甚至出现"API First"的设计思想。

2000 年,Roy Thomas Fielding 博士在他那篇著名的博士论文 《Architectural Styles and the Design of Network-based Software Architectures》中提出了几种软件应用的架构风格。 REST 作为其中的一种架构风格在这篇论文的第5章中进行了概括性的介绍。

REST 是一种很笼统的概念,它代表一种架构风格。 对于多个 Web 应用采用的架构,我们只能说其中某一个比其它的更具有 REST 风格, 而不能简单粗暴地说:“它采用了 REST 架构而其它的没有”。 为了将 REST 真正地落地,Lenoard Rechardson & Sam Ruby 在《RESTful Web Services》一书中 提出了一种名为“面向资源的架构(ROA: Resource Oriented Architecture)”。 该书中介绍了一些采用 ROA 架构的 Web 服务应该具备的基本特征。

RESTful Web API 设计只是 REST 风格架构设计中的一个环节,并没有统一的标准。下面介绍的是一些比较没有争议的实践原则。

实践原则

1.版本化你的 API

  应该尽量将 API 部署在专用域名之下。

    https://api.example.com

  如果确定 API 很简单,不会有进一步扩展,可以考虑放在主域名下。

    https://example.org/api/

  应该将 API 的版本号放入 URL。

    https://api.example.com/v1/

  另一种做法是,将版本号放在 HTTP 头信息中,但不如放入 URL 方便和直观。Github 采用这种做法。

2.URI 使用名词和 ID 而不是动词

  在 RESTful 架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词, 而且所用的名词往往与数据库的表格名对应。 一般来说,数据库中的表都是同种记录的"集合"(collection),所以 API 中的名词也应该使用复数。

举例来说,有一个 API 提供动物园(zoo)的信息,还包括各种动物和雇员的信息,则它的路径应该设计成下面这样。

    https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees

3.使用 HTTP 协议标准动词改变状态

  使用 PUT, POST 和 DELETE 方法 而不是 GET 方法来改变状态。 对于资源的具体操作类型,由 HTTP 动词表示。

  常用的 HTTP 动词有下面五个(括号里是对应的 SQL 命令)。

    GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
DELETE(DELETE):从服务器删除资源。

  还有两个不常用的 HTTP 动词。

    HEAD:获取资源的元数据。
OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。

  下面是一些例子。

    GET /zoos:列出所有动物园
POST /zoos:新建一个动物园
GET /zoos/ID:获取某个指定动物园的信息
PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID:删除某个动物园
GET /zoos/ID/animals:列出某个指定动物园的所有动物
DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物

4.过滤信息不涉及状态改变

  如果记录数量很多,服务器不可能都将它们返回给用户。API 应该提供参数,过滤返回结果。 常用的过滤包括分页、排序等等。 下面是一些常见的参数。

    ?limit=10:指定返回记录的数量
?offset=10:指定返回记录的开始位置。
?page=2&per_page=100:指定第几页,以及每页的记录数。
?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
?animal_type_id=1:指定筛选条件

  参数的设计允许存在冗余,即允许 API 路径和 URL 参数偶尔有重复。 比如,GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同的。

5.使用 Http 头声明请求和响应的格式

  在客户端和服务端,双方都要知道通讯的格式,格式在 HTTP-Header 中指定

    Content-Type 定义请求格式,比如 URL 格式
Accept 定义系列可接受的响应格式,JSON,XML 等等

  这个并不强制,实践中也可以通过参数来指定返回内容的格式

6.优先使用 JSON 格式返回结果

  当设计 API 返回结果时,优先使用 JSON 格式,但不强制。 当请求的 URL 表明的是一个集合时,则返回结果为数组形式。 例如:

        {
"data":[
{
"login": "jerry1",
"id": 1,
"avatar_url": "https://...."
},
{
"login": "jerry2",
"id": 2,
"avatar_url": "https://...."
},
{
"login": "jerry3",
"id": 3,
"avatar_url": "https://....",
}
]
}

  当请求为单个对象时,则返回结果为 MAP 形式。例如,访问 https://api.test.com/users/test 时:

        {
"login": "jerry4",
"id": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/1?v=3"
}

7.使用超媒体链接来组织文档

  Hypermedia as the Engine of Application State 超媒体作为应用状态的引擎,超文本链接可以建立更好的文本浏览体验。

  RESTful API 最好能做到 Hypermedia,即返回结果中提供链接,连向其他 API 方法,使得用户不查文档,也知道下一步应该做什么。

  比如,当用户向 api.example.com 的根目录发出请求,会得到这样一个文档。

        {
"link": {
"rel": "collection https://www.example.com/zoos",
"href": "https://api.example.com/zoos",
"title": "List of zoos",
"type": "application/vnd.yourformat+json"
}
}

  上面代码表示,文档中有一个 link 属性,用户读取这个属性就知道下一步该调用什么 API 了。 rel表示这个 API 与当前网址的关系(collection 关系,并给出该 collection 的网址), href 表示 API 的路径,title 表示 API 的标题,type 表示返回类型。

Hypermedia API 的设计被称为 HATEOAS。Github 的 API 就是这种设计,访问 api.github.com 会得到一个所有可用 API 的网址列表。

        {
"current_user_url": "https://api.github.com/user",
"authorizations_url": "https://api.github.com/authorizations",
// ...
}

从上面可以看到,如果想获取当前用户的信息,应该去访问 api.github.com/user,然后就得到了下面结果。

        {
"message": "Requires authentication",
"documentation_url": "https://developer.github.com/v3"
}

8.使用 Http 状态码处理错误

  如果你的 API 没有错误处理是很难的,只是返回 500 和出错堆栈不一定有用

  Http 状态码提供 70 个出错,我们只要使用 10 个左右:

    200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户得到授权(与 401 错误相对),但是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求 JSON 格式,但是只有 XML 格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

  使用详细的错误包装错误:

        {
"errors":[
{
"userMessage": "Sorry, the requested resource does not exist",
"internalMessage": "No car found in the database",
"code": 34,
"more info": "http://dev.mwaysolutions.com/blog/api/v1/errors/12345"
}
]
} just here , jerry

RESTful Web API 实践的更多相关文章

  1. 对RESTful Web API的理解与设计思路

    距离上一篇关于Web API的文章(如何实现RESTful Web API的身份验证)有好些时间了,在那篇文章中提到的方法是非常简单而有效的,我在实际的项目中就这么用了,代码经过一段时间的磨合,已经很 ...

  2. 我所理解的RESTful Web API [Web标准篇]

    REST不是一个标准,而是一种软件应用架构风格.基于SOAP的Web服务采用RPC架构,如果说RPC是一种面向操作的架构风格,而REST则是一种面向资源的架构风格.REST是目前业界更为推崇的构建新一 ...

  3. 我所理解的RESTful Web API [设计篇]

    <我所理解的RESTful Web API [Web标准篇]>Web服务已经成为了异质系统之间的互联与集成的主要手段,在过去一段不短的时间里,Web服务几乎清一水地采用SOAP来构建.构建 ...

  4. ASP.NET Web API实践系列04,通过Route等特性设置路由

    ASP.NET Web API路由,简单来说,就是把客户端请求映射到对应的Action上的过程.在"ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置"一 ...

  5. About Restful Web Api Something.

    这种轻量级的服务架构目前来说还是比较流行的,比如微信的公众平台的接口开发就是一个很好的案例,提到restful那么他到底是一个什么样的东西? REST(Representational State T ...

  6. 【ASP.NET MVC 学习笔记】- 19 REST和RESTful Web API

    本文参考:http://www.cnblogs.com/willick/p/3441432.html 1.目前使用Web服务的三种主流的方式是:远程过程调用(RPC),面向服务架构(SOA)以及表征性 ...

  7. RESTful Web API 理解

    REST 是一种应用架构风格,不是一种标准,是面向资源架构(ROA)风格,与具体技术平台无关,REST架构的应用未必建立在Web之上,与之对应的是传统的Web Service 采用的面向操作的RPC架 ...

  8. ASP.NET Web API实践系列07,获取数据, 使用Ninject实现依赖倒置,使用Knockout实现页面元素和视图模型的双向绑定

    本篇接着上一篇"ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API",尝试获取数据. 在Models文件夹下创 ...

  9. ASP.NET Web API实践系列05,消息处理管道

    ASP.NET Web API的消息处理管道可以理解为请求到达Controller之前.Controller返回响应之后的处理机制.之所以需要了解消息处理管道,是因为我们可以借助它来实现对请求和响应的 ...

随机推荐

  1. is not on any development teams

    is not on any development teams 1)账号正在申请中 2)申请成功后的账号? 加了3个账号,都是这样子的. 1:Xcode>Window> "Org ...

  2. Spring boot @PropertySource, @ImportResource, @Bean

    @PropertySource:加载指定的配置文件 /** * 将配置文件中配置的每一个属性的值,映射到这个组件中 * @ConfigurationProperties:告诉SpringBoot将本类 ...

  3. Spring mvc RequestContextHolder分析

    转载: http://blog.csdn.net/zzy7075/article/details/53559902

  4. Python 3 学习笔记(2)

    输入输出 str() 函数人类可读,repr() 解释器可读 rjust() 靠右,ljust() 靠左,center() 居中.zfill() 填0. 名字空间 名字到对象的映射关系被称为名字空间. ...

  5. HTML CSS + DIV实现整体布局 part1

    HTML CSS + DIV实现整体布局 1.技术目标: 开发符合W3C标准的Web页面 理解盒子模型 实现DIV+CSS整体布局 2.什么是W3C标准? W3C:World Wide Web Con ...

  6. struts2 防止表单重复提交--令牌机制

    jsp: action: 配置文件:

  7. Kconfig详解

    当执行#make menuconfig时会出现内核的配置界面,所有配置工具都是通过读取"arch/$(ARCH)Kconfig"文件来生成配置界面,这个文件就是所有配置的总入口,它 ...

  8. RN中关于ListView的使用

    1. ListView dataSource 介绍: ListView需要指定数据的来源.传入数据必须是数组,或者是字典里面嵌套数组 系统会根据你传入的数据自动生成section和row 每一个字典的 ...

  9. Django1.8:403错误:CSRF verification failed. Request aborted.

    问题:Django 403错误:CSRF verification failed. Request aborted.     原因:需要加cookie验证 解决方法: 1.在view.py中增加 fr ...

  10. jquery 不选择第一个

    参考 https://zhidao.baidu.com/question/174343639.html th:not(':first')