RESTful API知识整理

不是标准,是设计风格

REST(英文:Representational State Transfer,简称REST),通常应用在web应用程序中,提供一套满足特定的约束和原则的接口,用于客户端和服务器交互。REST并没有一个明确的标准,而更像是一种设计的风格。

来源于一篇论文

Roy Felding 在他论文 network based software architectures 中首次介绍了这些原则。

文章最后是论文下载链接(中文版)。80多页,概念很多,看起来有点无趣。哈哈。

意义深远

就像REST的作者所说的那样:

"本文研究计算机科学两大前沿----软件和网络----的交叉点。长期以来,软件研究主要关注软件设计的分类、设计方法的演化,很少客观地评估不同的设计选择对系统行为的影响。而相反地,网络研究主要关注系统之间通信行为的细节、如何改进特定通信机制的表现,常常忽视了一个事实,那就是改变应用程序的互动风格比改变互动协议,对整体表现有更大的影响。我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。"

基于HTTP

因为大部分用于web应用,底层通讯肯定还是http协议。比如GET,POST那些。这些也是客户端唯一可以访问服务端的方式。

URI

HTTP协议中有个很重要的概念:URI(注意不是URL,二者区别请自行搜索学习)

URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。在RESTful架构中,每个网址代表一种资源(resource)。

网上的一些例子,

ftp://ftp.is.co.za/rfc/rfc1808.txt (also a URL because of the protocol)
http://www.ietf.org/rfc/rfc2396.txt (also a URL because of the protocol)
ldap://[2001:db8::7]/c=GB?objectClass?one (also a URL because of the protocol)
mailto:John.Doe@example.com (also a URL because of the protocol)
news:comp.infosystems.www.servers.unix (also a URL because of the protocol)
tel:+1-816-555-1212
telnet://192.0.2.16:80/ (also a URL because of the protocol)
urn:oasis:names:specification:docbook:dtd:xml:4.1.2

从上面这个例子也可以看出,大部分REST API都是在某个域名之下,这也是实现REST API一个常用的方式。


知乎上的一个例子

比如在JDK中sun公司提供的简易HttpServer实现中

public void handle(final HttpExchange exchange)throws Exception

方法中,根据exchange对象可以拿到访问Http请求的URI对象,

ps:
http://127.0.0.1:8080/cmd_helloworld/?name=guowuxin

此时URI uri = exchange.getRequestURI();

通过uri可以拿到连接的各部分内容:

uri.getPath() --------------------> /cmd_helloworld 注意有斜杠
uri.getQuery()----------------------> name=guowuxin

作者:郭无心
链接:https://www.zhihu.com/question/21950864/answer/66779836
来源:知乎
著作权归作者所有,转载请联系作者获得授权。


应用实例

微博 API Error code

微博 API Error code

论文里对状态码有描述:

同样地,HTTP需要一个通用的规则来解释新的响应状态码,这样新的响应能够进行部 署而不会严重损害老的客户端。因此我们扩大了这个规则,规定每个状态码属于一个类别, 通过三位十进制数的第一位数字来表示:100-199表示消息中包含一个临时的信息响应, 200-299表示请求成功,300-399表示请求需要被重定向到另一个资源,400-499表示客户 端发生了一个不应该重复的错误,500-599表示服务器端遇到了一个错误,但是客户端稍后 可以得到一个更好的响应(或者通过某个其他服务器)。如果接收者不理解一个消息中的状 态码的特定语义,那么它们必须将该状态码按照与同一类别中状态码为x00时相同的方式来 处理。就像是方法名称的规则一样,这个可扩展性的规则在当前的架构上添加了一个需求, 这样架构就能够预见到未来的改变。改变因此能够被部署在一个现有架构之上,而无须害怕 出现不利的组件反应(adverse component reactions)。

Github API v3

Github API v3

比如我想获取一个github上的项目的详细信息,通过API可以拿到。

比如获取用户的基本信息,示例如下:

# GET /users/defunkt
curl https://api.github.com/users/defunkt

{
  "login": "defunkt",
  "id": 2,
  "url": "https://api.github.com/users/defunkt",
  "html_url": "https://github.com/defunkt",
  ...
}

另外有一点,Github API把版本号放在了URL的路径中,这个在很多参考资料中都不建议。一个很重要的原因是这样的设计,版本更新都会导致URL更新。不过这样设计的好处是方便直观,也有人推崇。

尽量使用JSON,避免使用XML

如果你做的项目多,会发现REST+JSON基本是个标准组合了。之所以没有用XML我觉得是JSON相对于XML更加简单,易读。作为开发者,我个人的经验是如果API响应的数据是JSON,我更容易发现里面的错误。

RESTful架构有一些典型的设计误区

最常见的一种设计错误,就是URI包含动词。因为"资源"表示一种实体,所以应该是名词,URI不应该有动词,动词应该放在HTTP协议中。举例来说,某个URI是/posts/show/1,其中show是动词,这个URI就设计错了,正确的写法应该是/posts/1,然后用GET方法表示show。

如果某些动作是HTTP动词表示不了的,你就应该把动作做成一种资源。比如网上汇款,从账户1向账户2汇款500元,错误的URI是:

  POST /accounts/1/transfer/500/to/2

正确的写法是把动词transfer改成名词transaction,资源不能是动词,但是可以是一种服务:

  POST /transaction HTTP/1.1
  Host: 127.0.0.1
  
  from=1&to=2&amount=500.00

另一个设计误区,就是在URI中加入版本号:

  http://www.example.com/app/1.0/foo
  http://www.example.com/app/1.1/foo
  http://www.example.com/app/2.0/foo

因为不同的版本,可以理解成同一种资源的不同表现形式,所以应该采用同一个URI。版本号可以在HTTP请求头信息的Accept字段中进行区分(参见Versioning REST Services):

  Accept: vnd.example-com.foo+json; version=1.0
  Accept: vnd.example-com.foo+json; version=1.1
  Accept: vnd.example-com.foo+json; version=2.0

一些好玩有用的资料

搜索API
APIs.io - the API search engine
ProgrammableWeb

Nytimes,使用这个API,开发者可以调用到几百万份结构化过的数据,从1981 年至今,纽约时报报道的事件,畅销书,甚至房地产等等
Nytimes


参考

  1. 理解RESTful架构
  2. 架构风格与基于网络的软件架构设计.pdf
  3. Web API Design
  4. Principles of good RESTful API Design
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式。”但是在要求详细讲述它所提出的各个约束,以及如...
    时待吾阅读 3,408评论 0 19
  • 去年有段时间得空,就把谷歌GAE的API权威指南看了一遍,收获颇丰,特别是在自己几乎独立开发了公司的云数据中心之后...
    骑单车的勋爵阅读 20,431评论 0 41
  • 一、什么是API? API(Application Programming Interface,应用程序编程接口)...
    Fairy_妍阅读 62,535评论 2 42
  • 前言:最近两年很火爆的网络框架Retrofit,使用它的时候,查看文档会告诉你,要求后台的服务器哥们必须符合RES...
    AWeiLoveAndroid阅读 94,802评论 10 93
  • 这几天我在用qq的时候突然看到搜搜第一条话题“第一批90后已经秃了”,觉得又莫名其妙又搞笑,第一批90后才多大啊,...
    青山半隐阅读 607评论 1 3