注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

逍遥子 曰:

得失失得 何必患得患失 舍得得舍 不妨不舍不得

 
 
 

日志

 
 

[译]优秀RESTful API的设计原则(三)  

2017-01-10 19:12:40|  分类: 架构设计 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

原文来自:https://codeplanet.io/principles-good-restful-api-design/

授权

多数情况下,服务器想确切知道每个请求的发起方是谁?当然,部分API接口能放开被用匿名访问,但通常接口只能被授权的用户访问。

OAuth2.0为此提供了一个很好的实现途径。你能知道每个请求是由哪个客户端发起?这些请求背后分别代表了哪些用户?以及提供一种标准化的用户访问或撤销访问方式,所有这些都无需第三方用户的登录授信。

还有OAuth1.0xAuth也能完成类似功能。无论采用那种方法,一定要确保通用性以和良好的文档设计,在文档中对用户常用语言/平台的各种不同封装库进行详细说明。[逍遥子笔记:这些服务以库的方式供客户端调用,例如SDK,因此在文档中要对各种形式的封装库进行详细说明]

我可以如实地告诉你,尽管OAuth1.0a虽然是最安全的选项,但是它非常难以部署。我遇到很多第三方开发人员抱怨他们不得不实现自己的库,因为OAuth1.0a没有他们所使用语言对应的库。我花费了大量的时间用于解决那些难以理解的“invalid signature”错误。因此,我建议你使用其他的替代方案。

内容类型

目前,大多数REST风格API接口都提供JSON格式的数据,你所能想起来的FacebookTwitterGitHub都是如此。XML方式已经逐渐退出人们的视野(除了一些大公司内部还在使用之外),幸亏SOAP方式已经消失,我们已经看不到返回HTML格式数据的API接口了。

开发者常用的开发语言或框架都能轻易解析你返回的各种有效数据。如果你正在使用不同的序列化器构建一个通用的返回对象,你可以使用前面提到的任意数据格式(SOAP除外),不过在返回数据时需要注意处理请求首部的Accept字段。[逍遥子笔记:HTTP请求头部的Accept可用于指定返回数据的格式]

一些API开发人员建议针对不同返回内容的类型,为URL(在端点之后)添加扩展字段,例如:.json.xml,或者.html,但我不建议这么做,我建议使用HTTP请求首部的Accept字段(HTTPRFC文档中有对Accept的解释),并且觉得这才是合适的方法。

超媒体API

超媒体API可能代表REST风格API的未来发展,它们在思想上更符合HTTPHTML的设计初衷。[逍遥子笔记:根据REST作者Roy Thomas Fielding的描述,REST核心是面向资源的设计,超媒体服务所提供了各种多媒体资源的访问,它在本质上符合了以资源为中心的设计]

在使用非超媒体的REST风格API时,URL端点也是客户端和服务器之间契约的一部分,这些端点必须事先告知客户端,一旦改变它们,客户端就无法按预期与服务器进行交互,这其实也是一种约束。

现在,API的用户不仅仅是能发起HTTP请求的用户代理,人们更常用浏览器发起HTTP请求。然而,用户不会被这些预先定义的、REST风格APIURL端点所约束。是什么让用户变得如此特殊呢?现在的网页能让用户先读主题,然后点击他们感兴趣的主题所对应的链接,访问他们想访问的网站或者想阅读的内容,此时URL发生变化的时候,用户不受影响(除非用户为某个网页打了标签,在他们访问这些打了标签的网页时会自动跳转到主页,用户需要再从主页中寻找他们所感兴趣数据的新路径)。[逍遥子笔记:我们的网站通常采用这种方式,尤其是各种门户网站,例如网易:www.163.com,新浪:www.sina.com,打开这些门户网站,我们看不到一个URL,我们所看到的都是一个个的主题,每个主题对应一个超链接(URL),当这些主题对应的URL发生变化时,只需要调整主题和超链接(URL)的映射关系即可,用户实际上看不到这些URL的变化]

超媒体API概念和一个普通人的行为类似。请求API的根目录将会获得一个URL列表,这些URL列表的每一项都可能对应了一个信息集,并且它以用户能够理解的方式来描述这些信息集合。无需为每个资源提供ID(除非特别邀请),因为一个URL就唯一标识了一个资源。

超媒体API用户在访问连接并且收集信息时,返回结果中将被放入最近更新的URL链接,因此URL无需事先与用户约定。如果URL被缓存了,后续请求又返回了404[逍遥子笔记:404表示请求了一个不存在的资源],用户只需简单地回到根目录重新寻找内容即可。

当从集合中检索一个资源列表时,要给用户返回这个资源列表的完整URL。当执行POST/PATCH/PUT请求时,可用返回码为3XX的响应来重定向到新的资源。

JSON即无法给我们提供需要的语义来指明哪些属性是URL,也不能说明URL怎样与当前的文档关联起来;可能正如你猜测的那样,HTML可以提供这样的信息。我们可以先通过API拿到数据,然后再进行HTML处理。想想CSS陪伴我们走过的这些路,我们可能有一天会看到:在获取同样URL和内容的时候,无论通过API请求还是网站访问,都采用同一种处理方式。[逍遥子笔记:JSON提供数据内容,并未提供数据展示功能]

文档

老实说,如果没有完全按照本文档的指导,你的API也不一定会太差,然而,如果你没有为API编写合适的文档,没有人会愿意用它,它将变为一个极难使用的API

确保你的文档无需授权便可被开发人员访问。

不要使用自动文档生成器,如果用了,就一定要仔细检查和修改生成的文档,确保它们能够被用户理解和使用。

文档中所举例子中的请求和响应包体要写全,不要截断不重要的部分,而是用高亮方式展示重要的部分。

文档中要写明各URL端点的预期返回码和可能的出错信息,以及出现这些错误信息的可能原因是什么?

如果时间充足,你还可以构建一个第三方开发人员使用的API控制台,以便他们可以立即对你的API进行验证。这个事情做起来不会像你想象的那么难,但是开发人员(包括内部开发人员和第三方开发人员)却可能因为这个功能而喜欢上使用你的API

确保文档能被打印,例如,CSS就是一种强大的文档展示方式;在文档打印的时候一定要隐藏文档的工具栏,即便没有人把你的文档用打印机打印出来,也会有很多开发人员喜欢把它们输出为PDF以便离线查看。

HTTP包解析

我们所有的事情都是通过HTTP完成,经常令我感到吃惊的是现还有很多人并不知道HTTP包是什么样子,这里我将给大家解析一个HTTP包。当用户发送一个HTTP请求到服务器时,在请求包里提供了一个key-value集合,叫做HTTP首部,紧随其后的是两个空行[逍遥子笔记:一个回车符一个换行符),最后是请求包体,所有这些都在同一个HTTP请求包内。

服务器对请求的响应包中也是以Key-Value格式的首部,紧接着是两个空行,然后是响应包体。HTTP是一种请求/响应协议,除非使用其他的协议,例如Websockets,否则服务端不会主动给客户端推送消息。

在设计API时,你最好借助能够查看HTTP包体的工具来协助设计,例如:Wireshark。同时要确保所使用的框架/web服务器能支持你尽可能多地读取和修改这些包体的字段信息。

HTTP请求包示例

POST /v1/animal HTTP/1.1

Host: api.example.org

Accept: application/json

Content-Type: application/json

Content-Length: 24

 

{

  "name": "Gir",

  "animal_type": 12

}


HTTP响应包示例

HTTP/1.1 200 OK

Date: Wed, 18 Dec 2013 06:08:22 GMT

Content-Type: application/json

Access-Control-Max-Age: 1728000

Cache-Control: no-cache

 

{

  "id": 12,

  "created": 1386363036,

  "modified": 1386363036,

  "name": "Gir",

  "animal_type": 12

}


 

  评论这张
 
阅读(175)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017