RESTful API 规划最佳实习-Android-优质IT资源分享社区

admin
管理员
管理员
  • UID1
  • 粉丝29
  • 关注4
  • 发帖数581
  • 社区居民
  • 忠实会员
  • 原创写手
阅读:296回复:0

  RESTful API 规划最佳实习

楼主#
更多 发布于:2016-06-02 20:52

布景

如今互联网上充满着许多的关于RESTful API(为了便利,今后API和RESTful API

一个意思)怎么规划的文章,可是却没有一个”全能“的规划规范:怎么鉴权?API格局怎么?你的API是不是应当参加版别信息?当你开端写一个app的时分,特别是后端模型有些现已写完的时分,你不得不绞尽脑汁的规划和完成自个app的public

API有些。由于一旦发布,对外发布的API将会很难改变。

在给SupportedFu规划API的时分,我企图以有用的视点来处理上面提到的疑问。我期望可以规划出简略运用,简略布置,而且满足灵敏的API,这篇文章因而而生。

API规划的根本恳求

网上的许多关于API规划的观点都十分”学院派“,它们或许更有理论根底,可是有时却和实习国际脱轨(因而我是自由派)。所以我这篇文章的方针是从实习的视点动身,给出当时网络运用的API规划最佳实习(当然,是我以为的最佳了~),假如觉得不合适,我不会遵从规范。当然作为规划的根底,几个有必要的准则仍是要恪守的:

当规范合理的时分恪守规范。

API应当对程序员友爱,而且在浏览器地址栏简略输入。

API应当简略,直观,简略运用的一起优雅。

API应当具有满足的灵敏性来支撑上层ui。

API规划权衡上述几个准则。

需求强调的是:API的即是程序员的UI,和别的UI相同,你有必要细心思考它的用户体会!

运用RESTful URLs 和action.

尽管前面我说没有一个全能的API规划规范。但的确有一个被遍及供认和恪守:RESTfu规划准则。它被Roy

Felding提出(在他的”根据网络的软件架构“论文中第五章)。而REST的中心准则是将你的API拆分为逻辑上的资本。这些资本经过http被操作(GET

,POST,PUT,DELETE)。

那么我应当怎么拆分出这些资本呢?

明显从API用户的视点来看,”资本“应当是个名词。即使你的内部数据模型和资本现已有了极好的对应,API规划的时分你依然不需求把它们一对一的都露出出来。这儿的关键是躲藏内部资本,露出必需的外部资本。

在SupportFu里,资本是 ticket、user、group。

一旦界说好了要露出的资本,你可以界说资本上答应的操作,以及这些操作和你的API的对应联络:

GET /tickets # 获取ticket列表

GET /tickets/12 # 检查某个详细的ticket

POST /tickets # 新建一个ticket

PUT /tickets/12 # 更新ticket 12.

DELETE /tickets/12 #删去ticekt 12

可以看出运用REST的优点在于可以充分利用http的强壮完成对资本的CURD功用。而这儿你只需求一个endpoint:/tickets,再没有别的啥命名规矩和url规矩了,cool!

这个endpoint的奇数复数

一个可以遵从的规矩是:尽管看起来运用复数来描绘某一个资本实例看起来别扭,可是共同一切的endpoint,运用复数使得你的URL愈加规整。这让API运用者愈加简略了解,对开发者来说也更简略完成。

怎么处理有关?关于怎么处理资本之间的办理REST准则也有有关的描绘:

GET /tickets/12/messages- Retrieves list of

messages for ticket #12

GET /tickets/12/messages/5- Retrieves message #5

for ticket #12

POST /tickets/12/messages- Creates a new message

in ticket #12

PUT /tickets/12/messages/5- Updates message #5 for

ticket #12

PATCH /tickets/12/messages/5- Partially updates

message #5 for ticket #12

DELETE /tickets/12/messages/5- Deletes message #5

for ticket #12

其中,假如这种有关和资本独立,那么咱们可以在资本的输出标明中保留相应资本的endpoint。然后API的运用者就可以经过点击连接找到有关的资本。假如有关和资本联络严密。资本的输出标明就应当直接保留相应资本信息。(例如这儿假如message资本是独立存在的,那么上面

GET

/tickets/12/messages就会回来相应message的连接;相反的假如message不独立存在,他和ticket依靠存在,则上面的API调用回来直接回来message信息)

不符合CURD的操作

对这个令人困惑的疑问,下面是一些处理办法:

重构你的做法action。当你的做法不需求参数的时分,你可以把active对应到activated这个资本,(更新运用patch).

以子资本对待。例如:GitHub上,对一个gists加星操作:PUT /gists/:id/star

而且取消星操作:DELETE /gists/:id/star.

有时分action真实没有难以和某个资本对应上例如search。那就这么办吧。我以为API的运用者关于/search这种url也不会有太大定见的(究竟他很简略了解)。只需留意在文档中写明白就可以了。

永久运用SSL

毫无例外,永久都要运用SSL。你的运用不知道要被谁,以及啥状况拜访。有些是安全的,有些不是。运用SSL可以削减鉴权的成本:你只需求一个简略的令牌(token)就可以鉴权了,而不是每次让用户对每次恳求签名。

值得留意的是:不要让非SSL的url拜访重定向到SSL的url。

文档

文档和API自身相同首要。文档应当简略找到,而且揭露(把它们藏到pdf里边或许存到需求登录的当地都不太好)。文档应当有展现恳求和输出的比如:或许以点击连接的办法或许经过curl的办法(请见openstack的文档)。假如有更新(特别是揭露的API),应当及时更新文档。文档中应当有关于何时弃用某个API的时刻表以及概况。运用邮件列表或许博客记载是好办法。

版别化

在API上参加版别信息可以有用的防止用户拜访现已更新了的API,一起也能让不相同首要版别之间平稳过渡。关于是不是将版别信息放入url仍是放入恳求头有过争辩:API

version should be included in the URL or in a header.

学术界说它应当放到header里边去,可是假如放到url里边咱们就可以跨版别的拜访资本了。。(参考openstack)。

strip运用的办法就极好:它的url里边有主版别信息,一起恳求头俩面有子版别信息。这么在子版别改变过程中url的安稳的。改变有时是不可防止的,关键是怎么办理改变。完好的文档和合理的时刻表都会使得API运用者运用的愈加轻松。

成果过滤,排序,查找:

url最佳越简略越好,和成果过滤,排序,查找有关的功用都应当经过参数完成(而且也很简略完成)。

过滤:为一切供给过滤功用的接口供给共同的参数。例如:你想约束get

/tickets 的回来成果:只回来那些open状况的ticket–get /tickektsstate=open这儿的state即是过滤参数。

排序:和过滤相同,一个好的排序参数应当可以描绘排序规矩,而不事务有关。杂乱的排序规矩应当经过组合完成:

GET /ticketssort=-priority- Retrieves a list of

tickets in descending order of priority

GET /ticketssort=-priority,created_at- Retrieves a

list of tickets in descending order of priority. Within a specific priority,

older tickets are ordered first

这儿第二条查询中,排序规矩有多个rule以逗号距离组合而成。

查找:有些时分简略的排序是不行的。咱们可以运用查找技能(ElasticSearch和Lucene)来完成(依旧可以作为url的参数)。

GET

/ticketsq=return&state=open&sort=-priority,created_at- Retrieve the

highest priority open tickets mentioning the word ‘return’

关于常常运用的查找查询,咱们可以为他们设立别号,这么会让API愈加优雅。例如:

get /ticketsq=recently_closed -> get

/tickets/recently_closed.

约束API回来值的域

有时分API运用者不需求一切的成果,在进行横向约束的时分(例如值回来API成果的前十项)还应当可以进行纵向约束。而且这个功用能有用的进步网络带宽运用率和速度。可以运用fields查询参数来约束回来的域例如:

GET

/ticketsfields=id,subject,customer_name,updated_at&state=open&sort=-updated_at

更新和创立操作应当回来资本

PUT、POST、PATCH

操作在对资本进行操作的时分常常有一些副作用:例如created_at,updated_at

时刻戳。为了防止用户屡次的API调用(为了进行这次的更新操作),咱们应当会回来更新的资本(updated

representation.)例如:在POST操作今后,回来201 created 状况码,而且包括一个指向新资本的url作为回来头

是不是需求 “HATEOAS

网上关于是不是答运用户创立新的url有很大的贰言(留意不是创立资本发生的url)。为此REST制定了HATEOAS来描绘了和endpoint进行交互的时分,做法应当在资本的metadata回来值里边进行界说。

(译注:作者这儿以为HATEOAS还不算老练,我也不怎么了解这段就算了,读者感兴趣可以自个去原文检查)

只供给json作为回来格局

如今开端对比一下XML和json了。XML即冗长,难以阅览,又不合适各种编程言语解析。当然XML有扩展性的优势,可是假如你仅仅将它来对内部资本串行化,那么他的扩展优势也发挥不出来。许多运用(youtube,twitter,box)都现已开端扔掉XML了,我也不想多费口舌。给了谷歌上的趋势图吧:

当然假如的你运用用户里边公司用户居多,那么也许需求支撑XML。假如是这么的话你还有别的一个疑问:你的http恳求中的media类型是应当和accept

头同步仍是和url?为了便利(browser

explorability),应当是在url中(用户只需自个拼url就好了)。假如这么的话最佳的办法是运用.xml或许.json的后缀。

命名办法?

是蛇形指令(下划线和小写)仍是驼峰命名?假如运用json那么最佳的应当是恪守JAVASCRIPT的命名办法-也即是说骆驼命名法。假如你正在运用多种言语写一个库,那么最佳按照那些言语所引荐的,java,c#运用骆驼,python,ruby运用snake。

自个定见:我总觉得蛇形指令更好使一些,当然这没有啥理论的根据。有人说蛇形命名读起来更快,能到达20%,也不知道真假http://ieeexplore.ieee.org/xpl/articleDetails.jsptp=&arnumber=5521745

默许运用pretty print格局,运用gzip

仅仅运用空格的回来成果从浏览器上看总是觉得很厌恶(一大坨有没有?~)。当然你可以供给url上的参数来操控运用“pretty

print”,可是默许开启这个选项仍是愈加友爱。分外的传输上的丢失不会太大。相反你假如忘了运用gzip那么传输功率将会大大削减,丢失大大增加。幻想一个用户正在debug那么默许的输出即是可读的-而不必将成果复制到别的啥软件中在格局化-是想起来就很爽的事,不是么?

下面是一个比如:

$ curl https://API.github.com/users/veesahni >

with-whitespace.txt$ ruby -r json -e 'puts JSON JSON.parse(STDIN.read)' <

with-whitespace.txt > without-whitespace.txt$ gzip -c with-whitespace.txt

> with-whitespace.txt.gz$ gzip -c without-whitespace.txt >

without-whitespace.txt.gz

输出如下:

without-whitespace.txt- 1252 bytes

with-whitespace.txt- 1369 bytes

without-whitespace.txt.gz- 496 bytes

with-whitespace.txt.gz- 509 bytes

在上面的比如中,多余的空格使得成果大小多出了8.5%(没有运用gzip),相反只多出了2.6%。据说:twitter运用gzip今后它的streaming

API传输削减了80%(link:https://dev.twitter.com/blog/announcing-gzip-compression-streaming-APIs).

只在需求的时分运用“envelope”

许多API象下面这么回来成果:

{"data" : {      "id" : 123,      "name" : "John"

  }}

理由很简略:这么做可以很简略扩展回来成果,你可以参加一些分页信息,一些数据的元信息等-这关于那些不简略拜访到回来头的API运用者来说的确有用,可是跟着“规范”的开展(cors和http://tools.ietf.org/html/rfc5988#page-6都开端被参加到规范中了),我自个引荐不要那么做。

何时运用envelope?

有两种状况是应当运用envelope的。假如API运用者的确无法拜访回来头,或许API需求支撑穿插域恳求(经过jsonp)。

jsonp恳求在恳求的url中包括了一个callback函数参数。假如给出了这个参数,那么API应当回来200,而且把真正的状况码放到回来值里边(包装在信封里),例如:

callback_function({     status_code: 200,    

next_page: "https://..",     response: {           ... actual JSON response body

...     }})

同样为了支撑无法办法回来头的API运用者,可以答应envelope=true这么的参数。

在post,put,patch上运用json作为输入

假如你认同我上面说的,那么你应当决议运用json作为一切的API输出格局,那么咱们接下来思考思考API的输入数据格局。

许多的API运用url编码格局:就像是url查询参数的格局相同:单纯的键值对。这种办法简略有用,可是也有自个的疑问:它没有数据类型的概念。这使得程序不得不根据字符串解分出布尔和整数,而且还没有层次构造–尽管有一些关于层次构造信息的约好存在可是和自身就支撑层次构造的json对比一下仍是不极好用。

当然假如API自身就很简略,那么运用url格局的输入没啥疑问。但关于杂乱的API你应当运用json。或许爽性共同运用json。

留意运用json传输的时分,恳求恳求头里边参加:Content-Type:applicatin/json.不然抛出415反常(unsupported

media type)。

分页

分页数据可以放到“信封”里边,但跟着规范的改善,如今我引荐将分页信息放到link

header里边:http://tools.ietf.org/html/rfc5988#page-6

运用link

header的API应当回来一系列组合好了的url而不是让用户自个再去拼。这点在根据游标的分页中尤为首要。例如下面,来自github的文档

Link:;

rel="next",; rel="last"

主动加载有关的资本

许多时分,主动加载有关资本十分有用,可以很大的进步功率。可是这却和RESTful的准则相背。为了如此,咱们可以在url中增加参数:embed(或许expend)。embed可以是一个逗号分隔的串,例如:

GET

/ticket/12embed=customer.name,assigned_user

对应的API回来值如下:

{    "id" : 12,    "subject" : "I have a

question!",    "summary" : "Hi, ....",    "customer" : {        "name" : "Bob"  

 },    assigned_user: {        "id" : 42,        "name" : "Jim",    }}

值得提示的是,这个功用有时分会很杂乱,而且也许致使N+1 SELECT 疑问。

重写HTTP办法

有的客户端只能宣布简略的GET

和POST恳求。为了照顾他们,咱们可以重写HTTP恳求。这儿没有啥规范,可是一个遍及的办法是承受X-HTTP-Method-Override恳求头。

速度约束

为了防止恳求众多,给API设置速度约束很首要。为此 RFC 6585

引入了HTTP状况码429(too many

requests)。参加速度设置今后,应当提示用户,至于怎么提示规范上没有阐明,不过流行的办法是运用HTTP的回来头。

下面是几个有必要的回来头(按照twitter的命名规矩):

X-Rate-Limit-Limit :当时时刻段答应的并发恳求数

X-Rate-Limit-Remaining:当时时刻段保留的恳求数。

X-Rate-Limit-Reset:当时时刻段剩下秒数

为啥运用当时时刻段剩下秒数而不是时刻戳?

时刻戳保留的信息许多,可是也包括了许多不必要的信息,用户只需求知道还剩几秒就可以再发恳求了这么也防止了clock

skew疑问。

有些API运用UNIX格局时刻戳,我主张不要那么干。为啥?HTTP 现已规则了运用 RFC 1123

时刻格局

鉴权 Authentication

restful

API是无状况的也即是说用户恳求的鉴权和cookie以及session无关,每一次恳求都应当包括鉴权证实。

经过运用ssl咱们可以不必每次都供给用户名和暗码:咱们可以给用户回来一个随机发生的token。这么可以极大的便利运用浏览器拜访API的用户。这种办法适用于用户可以首要经过一次用户名-暗码的验证并得到token,而且可以复制回来的token到今后的恳求中。假如不便利,可以运用OAuth

2来进行token的安全传输。

支撑jsonp的API需求额定的鉴权办法,由于jsonp恳求无法发送通常的credential。这种状况下可以在查询url中增加参数:access_token。留意运用url参数的疑问是:如今大有些的网络服务器都会讲query参数保留到服务器日志中,这也许会成为大的安全危险。

留意上面提到的仅仅三种传输token的办法,实习传输的token也许是相同的。

缓存

HTTP供给了自带的缓存框架。你需求做的是在回来的时分参加一些回来头信息,在承受输入的时分参加输入验证。根本两种办法:

ETag:当生成恳求的时分,在HTTP头里边参加ETag,其中包括恳求的校验和和哈希值,这个值和在输入改变的时分也应当改变。假如输入的HTTP恳求包括IF-NONE-MATCH头以及一个ETag值,那么API应当回来304

not modified状况码,而不是惯例的输出成果。

Last-Modified:和etag相同,仅仅多了一个时刻戳。回来头里的Last-Modified:包括了

RFC 1123 时刻戳,它和IF-MODIFIED-SINCE共同。HTTP规范里边有三种date格局,服务器应当都能处理。

犯错处理

就像html过错页面可以显现过错信息相同,API

也应当能回来可读的过错信息–它应当和通常的资本格局共同。API应当一直回来相应的状况码,以反映服务器或许恳求的状况。API的过错码可以分为两有些,400系列和500系列,400系列标明客户端过错:如过错的恳求格局等。500系列标明服务器过错。API应当至少将一切的400系列的过错以json方式回来。假如也许500系列的过错也应当如此。json格局的过错应当包括以下信息:一个有用的过错信息,一个唯一的过错码,以及任何也许的详细过错描绘。如下:

{"code" : 1234,"message" : "Something bad happened

","description" : "More details about the error

here"}

对PUT,POST,PATCH的输入的校验也应当回来相应的过错信息,例如:

{    "code" : 1024,    "message" : "Validation

Failed",    "errors" : [        {             "code" : 5432,             "field"

: "first_name",             "message" : "First name cannot have fancy

characters"       },       {             "code" : 5622,             "field" :

"password",             "message" : "Password cannot be blank"      }   ]}

HTTP 状况码

200 ok  - 成功回来状况,对应,GET,PUT,PATCH,DELETE. 201

created  - 成功创立。 304 not modified   - HTTP缓存有用。 400 bad request   - 恳求格局过错。 401

unauthorized   - 未授权。 403 forbidden   - 鉴权成功,可是该用户没有权限。 404 not found - 恳求的资本不存在

405 method not allowed - 该http办法不被答应。 410 gone - 这个url对应的资本如今不可用。 415

unsupported media type - 恳求类型过错。 422 unprocessable entity - 校验过错时用。 429 too many

request - 恳求过多。

优质IT资源分享社区为你提供此文。

站有大量优质android教程视频,资料等资源,包含android基础教程,高级进阶教程等等,教程视频资源涵盖传智播客,极客学院,达内,北大青鸟,猎豹网校等等IT职业培训机构的培训教学视频,价值巨大。欢迎点击下方链接查看。

android教程视频

优质IT资源分享社区(www.itziyuan.top)
一个免费,自由,开放,共享,平等,互助的优质IT资源分享网站。
专注免费分享各大IT培训机构最新培训教学视频,为你的IT学习助力!

!!!回帖受限制请看点击这里!!!
!!!资源失效请在此版块发帖说明!!!

[PS:按 CTRL+D收藏本站网址~]

——“优质IT资源分享社区”管理员专用签名~

本版相似帖子

游客