RESTful API 实践

什么是 REST?

REST 即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格(http://www.ics.uci.edu/~field...)。它是一种针对网络应用的设计和开发方式,能够下降开发的复杂性,提升系统的可伸缩性。html

六个约束:

  • 统一接口(Uniform Interface)git

  • 无状态(Stateless)github

  • 缓存(Cacheable)api

  • 客户-服务器(Client-Server)xcode

  • 分层系统(Layered System)缓存

  • 按需代码(Code on Demand)服务器

统一接口(Uniform Interface)

使REST 架构风格区别于其余基于网络的架构风格的核心特征是,它强调组件之间要有一个统一的接口。经过在组件接口上应用通用性的软件工程原则,总体的系统架构获得了简化,交互的可见性也获得了改善。实现与它们所提供的服务是解耦的,这促进了独立的可进化性。然而,付出的代价是,统一接口下降了效率,由于信息都使用标准化的形式来转移,而不能使用特定于应用的需求的形式。REST 接口被设计为能够高效地转移大粒度的超媒体数据,并针对Web的常见状况作了优化,可是这也致使了该接口对于其余形式的架构交互并非最优的。restful

无状态(Stateless)

通讯必须在本质上是无状态的,所以从客户到服务器的每一个请求都必须包含理解该请求所必需的全部信息,不能利用任何存储在服务器上的上下文,会话状态所以要所有保存在客户端。网络

缓存(Cacheable)

为了改善网络的效率。缓存约束要求一个请求的响应中的数据被隐式地或显式地标记为可缓存的或不可缓存的。若是响应是可缓存的,那么客户端缓存就能够为之后的相同请求重用这个响应的数据。架构

客户-服务器(Client-Server)

经过分离用户接口和数据存储这两个关注点,咱们改善了用户接口跨多个平台的可移植性;同时经过简化服务器组件,改善了系统的可伸缩性。然而,对于 Web来讲,最重要的是这种关注点的分离容许组件独立地进化,从而支持多个组织领域的Internet规模的需求。

分层系统(Layered System)

分层系统风格经过限制组件的行为(即,每一个组件只能“看到”与其交互的紧邻层),将架构分解为若干等级的层。经过将组件对系统的知识限制在单一层内,为整个系统的复杂性设置了边界,而且提升了底层独立性。咱们可以使用层来封装遗留的服务,使新的服务免受遗留客户端的影响,经过将不经常使用的功能转移到一个共享的中间组件中,从而简化组件的实现。中间组件还可以经过支持跨多个网络和处理器的负载均衡,来改善系统的可伸缩性。

按需代码(Code on Demand)

经过减小必须被预先实现的功能的数目,简化了客户端的开发。容许在部署以后下载功能代码也改善了系统的可扩展性。然而,这也下降了可见性,所以它只是 REST 的一个可选的约束。

HTTP 动做

GET

HTTP GET 用于检索(读取)资源。正确的状况返回JSON200 HTTP响应码,在错误的状况下他们一般返回404(NOT FOUND)400(BAD REQUEST)

示例

GET http://www.example.com/custom...
GET http://www.example.com/custom...
GET http://www.example.com/bucket...

经过GET它应该永远不会修改服务器上的任何资源。

POST

HTTP POST 一般用于建立资源。正确的状况返回201 HTTP响应码及Location header(资源 URI)。

示例

POST http://www.example.com/customers
POST http://www.example.com/custom...

PUT

HTTP PUT 一般用于更新资源。将请求正文内容替换已知资源的原始数据。

示例

PUT http://www.example.com/custom...
PUT http://www.example.com/custom...

DELETE

HTTP DELETE 用于删除由URI标识的资源。成功删除返回200 HTTP及响应正文或没有正文响应204 HTTP(NO CONTENT)

示例

DELETE http://www.example.com/custom...
DELETE http://www.example.com/custom...
DELETE http://www.example.com/bucket...

下表是 URI 结合 HTTP METHOD 建议的返回值

HTTP Verb(Method) /customers /customers/{id}
GET 200 (OK)。客户列表,数据量大可以使用分页排序筛选 200 (OK)。单个客户。404 (Not Found) ID客户不存在,400 (BAD REQUEST) ID不合法
POST 201 (Created),'Location' header 为 /customers/{id} 包含新的资源ID 404 (Not Found)
PUT 404 (Not Found) 200 (OK)或者204 (No Content)。404 (Not Found) ID客户不存在,400 (BAD REQUEST) ID不合法
DELETE 404 (Not Found) 200 (OK)或者204 (No Content)。404 (Not Found) ID客户不存在,400 (BAD REQUEST) ID不合法

资源命名

一切在工艺软件开发的命名是成功的关键。

除了适当的应用 HTTP Verb(Method),资源命名能够说是最受争议和最重要的概念。当资源被命名好时,API 是直观和易于使用的。作得太差,一样的 API 能感受太表面化和难以使用和理解。下面是一些提示,让你去当建立资源 URI 为您新的 API。

资源 URI 应使用名词而不是动词命名。一个 RESTful URI 应该指一种资源,而不是采起行动。名词具备属性而动词没有。

服务套件中每一个资源至少有一个 URI 标识它。URI 应遵循一种可预见,分层结构,以增长可理解性,从而提升可用性。

在一个订单系统与客户、订单、行项目的资源设计:

建立一个新的客户
POST http://www.example.com/customers

读取客户 ID 为 33245
GET http://www.example.com/custom...
相同的 URI 将用于更新(PUT)与删除(DELETE)客户

这里为产品设计的 URI:
POST http://www.example.com/products
建立一个新的产品

GET|PUT|DELETE http://www.example.com/produc...
读取、更新、删除 ID 为 66432 的产品为

如今变得颇有趣,咱们如何为客户建立新的订单?
一种选择是
POST http://www.example.com/orders
毫无疑问它是能够工做的,但它却在客户的上下文以外

下面的 URI 更清晰
POST http://www.example.com/custom...
如今咱们知道这个订单是为客户 33245 建立的

获取 33245 客户订单使用以下 URI
GET http://www.example.com/custom...
如今,咱们继续来看分层的 URI 设计。以下:
POST http://www.example.com/custom...
这会将行项目添加到订单 #8769(这是客户 #33245),获取该 URI 资源会返回订单下全部的行项目,若是行项目毫无心义或者在客户的上下文之外的地方能感受到咱们会提供这样一个 URI
POST www.example.com/orders/8769/lineitems

看看一些普遍使用的 API 来获得资源命名窍门和利用你的队友来完善您的 API 资源。

Response Body

简单响应

示例

{
   "url":"https://api.github.com/gists/20c98223d9b59e1d48e5",
   "id":"1",
   "description":"description of gist",
   "public":true,
   "user":{
       "login":"octocat",
       "id":1,
       "avatar_url":"https://github.com/images/error/octocat_happy.gif",
       "gravatar_id":"somehexcode",
       "url":"https://api.github.com/users/octocat"
   },
   "comments":0,
   "comments_url":"https://api.github.com/gists/19d18b30e8af75090307/comments/",
   "html_url":"https://gist.github.com/1",
   "git_pull_url":"git://gist.github.com/1.git",
   "git_push_url":"git@gist.github.com:1.git",
   "created_at":"2010-04-14T02:15:15Z"
}

分页响应

  • total_count 总记录数

  • items 数据项

示例

{
   "total_count":40,
   "items":[
       {
           "id":3081286,
           "name":"Tetris",
           "full_name":"dtrupenn/Tetris",
           "owner":{
               "login":"dtrupenn",
               "id":872147,
               "type":"User"
           },
           "private":false,
           "html_url":"https://github.com/dtrupenn/Tetris",
           "description":"A C implementation of Tetris using Pennsim through LC4",
           "fork":false,
           "url":"https://api.github.com/repos/dtrupenn/Tetris",
           "created_at":"2012-01-01T00:31:50Z",
           "updated_at":"2013-01-05T17:58:47Z",
           "pushed_at":"2012-01-01T00:37:02Z"
       }
   ]
}

错误响应

  • code 错误码

  • message 错误信息

示例

{
   "code": 12345,
   "message": "错误描述"
}

参考资源

http://www.restapitutorial.com/
https://www.oschina.net/trans...

相关文章
相关标签/搜索