分享 Modern Web API Desgin

hooopo for Shopper+ · 2013年08月03日 · 最后由 bhuztez 回复于 2013年08月12日 · 7818 次阅读
本帖已被管理员设置为精华贴

拥抱 REST

现在,大部分主流网站都使用 RESTful 风格的 API 作为交互接口。REST 几乎成了 API 的事实标准,无论是内部 API 还是外部 API。这并不奇怪,因为 REST 的可伸缩性、可扩展性、低耦合等特性无疑是最适合做 Web API 不过了。

虽然各个网站 API 都标榜自己是 REST,但从对 REST 的理解和实践上还有蛮多差别,我个人最欣赏的是Github V3 的设计

从 Server-Side API 到 Client-Side API

先解释一下 Server-Side API 和 Client-Side API:

  • Server-Side API 主要指用户请求第三方服务器,第三方服务器再去调用 API 服务器这样的通讯方式。
  • Client-Side API 与 Server-Side API 对应,指用户直接绕过第三方服务器,直接通过浏览器与 API 服务器交互。

Server-Side API 的缺点

  • 调用者使用起来麻烦
  • 需要大量的异常处理
  • 容易堵塞第三方服务器
  • 不容易利用缓存
  • 不环保

Client-Side API 的优点

  • 使用方便,一般只需要引入一段 JS
  • 无需关心异常,因为浏览器有天然的容错机制,不会像服务器那样,一个异常就让整个请求挂掉
  • API 在浏览器里运行,不需要考虑超时处理、进程堵塞等一系列问题
  • 浏览器是最强大的 HTTP 客户端,自带各种缓存机制
  • 数据从用户浏览器直接发送到 API 服务器,不需要经过任何中间层。

现有的 Client-Side API

上面的功能各异,从关注、发推、评论到统计甚至支付。实现方式各异,从最简单的 JSONP 形式到动态 IFrame,但都把复杂留给了 API 服务提供端,把方便留个了 API 调用者。在处理跨域问题上有很多技术难点,但 Client-Side API 相比 Server-Side API 在给开发者带来的体验是有了质的飞越。

Client-Side API Over Server-Side API

我的观点是,一个和需要用户交互的 API 服务,如果能设计成 Client-Side 就不要设计成 Server-Side 的。

关于安全

不懂安全的人喜欢把一个东西设计的很麻烦来让人觉得这是安全的,典型的例子是支付宝

JSONP 作为跨域 Client-Side API 的最主要方式,在传输敏感数据会有 JSONP Leak 漏洞,但是也可以通过 per-sign 的方式避免的。

甚至像 Amazon S3 图片上传这样的功能也可以做成 Client-Side 的,并且很安全。

第三方服务器通过生成一个用 secret key预签名的表单,用户直接从浏览器把图片传到 S3 服务器,S3 服务器成功接收图片之后 callback 给第三方服务器。但是由于 S3 不能在云端对图片进行缩放等处理,遇到需要将一张图片生成不同尺寸图片这种需求会麻烦些。不过七牛做的就比较完美了,不但支持客户端直传图片,而且支持云端图片处理。

最讨厌 REST 了

要开战吗?

阐述的内容难道不是:

REST API 与 Third-Party Web Widget.

#3 楼 @Saito yes,Web API 的本质是让第三方以一个更灵活的方式利用服务方的资源。

Web API 也好,Third Party Web Widget(或 Third Part Javascript)也好,都是用来实现这个目的的手段。设计 API 的时候不应该考虑的是设计 REST API 还是 Third Party Web Widget,首先考虑的应该是第三方调用的方不方便。

Third-Party Web Widget 和普通 REST API 的界限不是很明显。比如一个返回 JSON 的 API 加一个 callback 立马就成立 JSONP 调用,就更 Web Widget 化了..

还有 S3 上传的例子,其实就是普通的 Web API,但却可以设计得很 Web Widget.

我想阐述的就是 API 应该离用户越近越好,如果可能的话,这是努力的方向。

#4 楼 @hooopo Third-Party Web Widget 比 REST API 提供的难度要大得多。

首先要确保自己有精力来实现,还要有强有力的设计人员确保大部分站点应用后不会显得突兀。

做不好完全是吃力不讨好的行为。

之前设想过如果有足够多的 Third-Party Web Widget, 我是不是不用写代码就可以搭建网站了。

两者还有一个巨大差别,REST API 一定是官方提供的,而 Third-Party Web Widget 任何人都可以写。

#6 楼 @Saito Third-Party Web Widget 的难度确实挺大的,涉及到跨域请求、跨域消息传递、第三方 cookie、Embedding Iframe Style 等一系列棘手问题。但我觉得技术就是用来解决问题的,不写代码就可以搭建网站(利用网站的某个功能)是每个开发者都想要的啊。。

举个最简单的例子,一个大型网站的各个子网站都需要评论功能,花时间和精力开发一个好用的 Comment Web Widget 难道不值得么?同时也给其他项目节省了大量时间和资源。服务提供方作为一个平台,花一点精力去做些提升性能和易用性的工作是完全值得的。其实 Third Party Web Widget 也解决了 REST API 版本发布的最大难题,发布之后就要一直维护已有的接口,给升级带来痛苦。

做不好完全是吃力不讨好的行为。

任何事情做不好都是一样....

两者还有一个巨大差别,REST API 一定是官方提供的,而 Third-Party Web Widget 任何人都可以写。

Third-Party Web Widget 也必须 API 提供方自己域提供呀(因为涉及到 session 信息),除非是简单的 Proxy,才任何人都可以写。

#7 楼 @hooopo http://ghbtns.com/ Widget 不一定需要 Session 信息,例如查询天气,Github 指定 Repo 的浏览代码 Widget, Twitter 指定用户的 Tweets 列表。

另外。Third-Party Web Widget 可以基于 REST API 构建出来,他们本来就是架构的两层。

我说的吃力不讨好是因为,REST API 是必须的,你必须做好。Widget 是加分项,做的不好。整体反而会减分。

一个大型网站的子网站就不需要 Third-Party Web Widget 了,自己做一个评论框,大家都用这个 POST 到同一个数据库就行了。

#8 楼 @Saito 你说的 unofficial 能做的 Widget 应该是和认证不相关的,但是这种好像不多吧。

一个大型网站的子网站就不需要 Third-Party Web Widget 了,自己做一个评论框,大家都用这个 POST 到同一个数据库就行了。

没那么简单 各个子站也不是同一个团队开发的,也需要 API,并且需要跨子域,如果有点 Ajax 效果就更不好处理了。

还有就是即使是子站,有些时候也未必都使用子域名,这个不是开发者能决定的。

server side api 本身把请求包了一下对网速是个严重的影响。而且确实很容易阻塞第三方服务器,第三方服务器苦逼的做了 api 的搬运工。

有个问题想请教一下,在 HTTP 的规范,发起 PUT 方法的时候,请求体不会被当成参数,而是当成输入流的。

这种时候的后台应该如何解析呢?(我问的针对 PUT 提交 form 的这样的普遍情况,不是特指 ruby on rails 的 PUT 提交的操作)

非常感兴趣,期待更多类似内容。

Third-Party Web Widget……把原本属于后端的职责放在前端,以后搭网站直接加几个 Widget 就行了,这可以叫“前端云”么?

(Cloud -> 前端 MVC -> 前端 Cloud,看来以后的 Web 就是一段 Javascript 和后端的数据库了。)

#11 楼 @ywjno 这个还真不清楚呢

#15 楼 @hooopo 请教一下,有了解过 hypermedia API 么?

#15 楼 @hooopo 最近刚好研究一些跨站的信息传递问题,多谢!

请教一个文件上传进度条的问题: 我在用 carrierwave 上传文件到自己的 server 时,进度条工作很正常。但是一旦把上传目的地配置成第三方(例如 upyun),进度条就不工作了。不知大家有无遇到过这个问题?

#15 楼 @hooopo CORS 算了,JSONP 安全问题折腾死

#18 楼 @bhuztez 可是 cors 不兼容问题更大 除非 ie6-8 都死掉。

#19 楼 @hooopo IE8 有 XDomainRequest。

IE6 可以试试htmlfile

需要 登录 后方可回复, 如果你还没有账号请 注册新账号