瞎扯淡 Restful API Base Server 的小小讨论

soloara · February 24, 2012 · Last by yuan replied at March 04, 2012 · 8848 hits

首先不知有多少朋友写过纯 API BASE 的 App Server? 想统计一下 Pure Api Base 的 Server 在国内有哪些。

再次 Restful 的 Api 应该用 put、delete。 还是因为一些客户端的实现问题把 put 和 delete 改为 uri 中的 path 比较好。 比如:

:put => '/users/1/update', :via => :post
:delete => '/users/1/destroy', :via => :post

这样就不纯了。Rails 本身的约定不就很好,post _method 参数做兼容

#1 楼 @Rei 我本身的做法也是用的 put,delete 但在实际情况中,很多客户端的库本身对 restful 概念的支持就不好,牵强的硬去加_method 反而容易让程序人员很困惑。(因为他们冲 url 中看到的是老在请求同一个地址),其实 Rails 下面的 Restful Api 框架 Grape 本身也比较推荐这种稍微变异的方式: 这是他的例子

resource :statuses do
  get :public_timeline do
    Tweet.limit(20)
  end

  get :home_timeline do
    authenticate!
    current_user.home_timeline
  end

  get '/show/:id' do
    Tweet.find(params[:id])
  end

  post :update do
    authenticate!
    Tweet.create(
      :user => current_user,
      :text => params[:status]
    )
  end
end

这种讨论不先定义好什么是 REST 很难继续下去..

当然,定义好了 也就不需要讨论了:-)

什么是纯 api?纯 api 还要用 grape?据说 grape 依托 rails 的。为什么不用 sinatra?

Put,Delete,看你的 api 谁用的,自家手机客户端用或是内部 service api,我觉得你还是直接 put 和 delete。要是浏览器还要 consume 的话,那就换 rails 那种。

API 超难写,个人感觉,做过个玩具,要想写得漂亮就各种纠结。lz 可以看看 Service-Oriented Design With Ruby and Rails 这本书,挺有帮助的。

#3 楼 @hooopo = =再看一遍顶楼发现是说“纯 API Server”

#4 楼 @clc3123 grape 完全可以不依托 rails,就只上个 mongoid 或者 ActiveRecord 就没有问题啊。 如果是 Open API 的话,put、delete 会不会有时太强人所难了。 我还是说 grape 可以把 API 写得很漂亮且容易管控,您可以去看看 grape 的例子,它本身也是说的自己是原生 restful 的框架。 Restful 本质就是资源化,把_method 里面的 put、delete 提到 path 里面难不成就不算资源化了?一定要夹在_method 里面才叫资源化,这种理解是否太狭隘,请拍砖。

#6 楼 @soloara 把 method 放到 url 里面就是不 Restful 的,不过很可惜,浏览器就是不 Restful 的。所以 Rails 的妥协是实现 Restful 的基础上提供兼容的非 Restful method,等到浏览器支持所有 HTTP method 之后再去掉。

从实际情况出发,我也同意不一定非要 Restful,这东西还是偏学术一点。

#7 楼 @Rei "把 method 放到 url 里面就是不 Restful 的",从真实的 restful 实现里面我能理解,但从 restful 意义的本身上来说我就不理解了。这里的问题是 restful 的本质是什么?

#8 楼 @soloara 哈哈 终于回到本质了

#6 楼 @soloara 你这么一说,我看了下 grape,还是比较轻量的,挺不错!Grape 搭配 rails,是不是也是需要把 controller 逻辑重复一遍呢?不过提供简单的 api,确实很容易维护。 我写 api 时,参考过新浪等,发现他们的回传 json 都结构很复杂,一开始不理解,但是后来才知道主要是方便客户端操作,减少请求,纠结就纠结在这两点了。。。 另外我使用了一个 build json 的 gem,这样把 json 的操作放到 view 里去,controller 也显得干净。

#10 楼 @clc3123 不需要啊,其实 ActiveRecord 的 as_json 就已经非常强大了,很多参数可选的。

#9 楼 @hooopo 虎跑你是傻帽

讨论 rest 的帖子总是让我很别扭,不如发明一个新词吧,比如——DIWHAT(Data Interface With Http As the Transport protocol) ?

#13 楼 @fsword 请问怎么别扭这这位了?

#14 楼 我猜想 @hooopo 同学应该也是这个意思吧,REST 这个词有明确定义,可还是总被滥用

#15 楼 @fsword 装逼的人,鉴定完毕。Hooopo 的 RESTFUL 本来就很烂的,RESTFUL 里面确实定义的 PUT、DELETE 作为标准方法。不过请看我在二楼说的,这是一种变异,沽名垂钓的装逼男。

#15 楼 @fsword 我要继续骂你,杭州的上次 conf,拿出来的传代码的傻逼 API 还不够你们回去自省吗?还要来丢人显眼。

#17 楼 @soloara 骂人我不太擅长,就不和你比了。不过你说的杭州 conf 云云,我不明白是怎么回事?我当时在场么?

楼主,火气怎么这么大。 人身攻击不解决任何问题。。反而会被大家鄙视。。

#19 楼 @ywencn 对人才能用“人身攻击”。在您提醒之前我没有意识到 SORRY。

REST 是一种架构风格... 明确的定义也并不一定能帮助你做好实践... 目前很多人对它的认识和理解也是有差异的...

至于用什么 http method...url 长什么样...这只是一个很表皮的问题... @fsword 所以取什么 DIWHAT 更是万万不可....(除非你为这个表皮的事情专门取个名字)

Rails 的规约并不是不能打破...前提是你要刻意去打破,而不是无意打破... 楼主如果是有意为之我倒是没觉得有什么不妥....

本来是个讨论实践的帖子,后头搞得来讨论形而上的东西....可惜....

这就好像一个讨论 TDD 的帖子,扯到什么敏捷一样... 可惜可惜....

#21 楼 @ywencn 确实不好意思,比较激动,不过我亦依然认为 @fsword 的行为在 ruby 社区里面非常负面。

#10 楼 @clc3123 如果是纯 api based 的 app。你甚至就用 grape 都可以...完全可以不走 controller... 你自己网站对于你的 server 就是一个 js client.... 但是目前其实很多应用都没那么纯,甚至很多走的是两套... 一套用于自己的页面,一套用于 api...

哟 怎么回了两个帖子 就变成骂战了???

#25 楼 @poshboytl 我在嘛他,他没骂我,他比较清高。

看了两个贴,原本都是好好的技术讨论贴,怎么最后味道就变了? 有句话说“虽然我不赞成你的做法但是我誓死捍卫你说话的权利!” 我觉得应该把精力都放在问题本身上,不同的想法做法才能比较出优劣,吸其精华弃之糟粕。

#27 楼 @miclle 我很虚心的讨教,结果有人上来就摆谱。

#22 楼 @poshboytl 把概念定义清楚才能不至于浪费口水,而 REST 的概念已经被其作者拨乱反正过一回了,相信大家应该都看过这篇文章 http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven 或者中文翻译 http://www.infoq.com/cn/news/2008/12/restapi-must-be-hypertext-driven ,所以我对社区里这种拿着 data api 说 REST 的讨论很反对,大家应该看出来取名字是一句讽刺,其实数据接口的设计和 REST 没有什么关系,它大量定义了先验知识,更不用说超文本驱动,所以讨论是否更 RESTFul 没有意义。

去掉 REST 这个名字还有一个用处,我们不必为了 REST 而 REST,既然本来就不是 REST 的思路,那么就老老实实设计我们的接口 url,其实,如果不是为了符合 Rails 的路由习惯等等因素,你的 url 怎么设计都行的,只要有规律,确保一致性即可

最后补一句,@soloara 对我的判断只是他个人观点,我没兴趣反驳。不过这是一个社区,他的个人观点显然不能左右我,如果大家都这么想的话,我倒是会考虑离开这个社区

很多客户端的库本身对restful概念的支持就不好

弱弱的问一下很多是指哪些客户端? #2 楼 @soloara 你举的那个 grape 的例子想说明什么?

MTK 机上面这就是个切实的问题。 grape 只是说明 grape 的作者也并不认为必须用 delete、和 put。我只是问问大家的意见。

“真正的 RESTful API”就想超文本一样,信息的每个寻址单元显式地(如,link 和 id 属性)或隐式地(如,由媒体类型定义和表示结构推导而来)携带一个地址。REST API 不应该依赖于任何通信协议,尽管要成功映射到某个协议可能会依赖于元数据的可用性、所选的方法等。 作者自己的意思,摘至 fsword 于 22 楼发表的帖子。 so:@Rei也许这并不是不纯

#29 楼 @fsword 请君看清题,API 和 REST 是两个问题其中“再次”二字表述出来了。

#29 楼 @fsword 哦,我理解你的意思了。你是希望为定义接口的行为专门定义新的名词以做区分?

我倒是觉得没必要啊,Restful API 这个词语不是蛮好的吗?这里 Restful 是个形容词,重点是讨论 api。而从帖子来看,本来也就是个讨论 api 的帖子....

本来是一个实践性的帖子...怎么就搞成谈论形而上学了?

说简单点,我估计楼主的意思就是... 他为了将就一些人或者情况(我猜测是他们客户端团队),他打算不用 delete 和 put 两个动作,想问问有没有人也这么干过。多么简单的个问题。哪里有必要讨论什么形而上的东西...

@soloara 我就这么干过。可能是 4 年前了。因为做客户端的同事不懂什么是 put 和 delete,他也不见得赞同。当时工期非常紧张,与其和他讨论半天,我不如去将就他。本来也不是个大问题,只要明确是刻意打破的就行了...

#4 楼 @clc3123 因为你的头像,不得不提醒告诉你信息的这个人不可相信...

#34 楼 @poshboytl 我刚在代码里用了/posts/:id/delete 这样的 url...

Rest 本来就只是一种 MVC 的组织方式,就@fsword 的说法,API 就不可以用 RESTful 了?我们在定义 API 的时候就不应该扯上和 Restful 有关系了,是吗?DIWHAT 是一种什么架构理念啊?请您回答一下?我重申我只是想把我的 API 中资源接口的 delete 和 put 做得更加兼容一点。

#34 楼 @poshboytl 这个就见仁见智了,我很喜欢老外讨论问题的方式,讨论前先把概念约定一致。

#36 楼 @yedingding 哈哈哈哈~ 所以啊...我觉得没什么的... 只要明确自己这么干咯... :D

Rest本来就只是一种MVC的组织方式 ,看到这句话有些无语。 @poshboytl ,我觉得强调概念还是很必要的

#40 楼 @fsword 那你来澄清一下概念吧。我承认,我连 REST 那篇论文都没好好读过一遍...

#39 楼 @poshboytl 以前才学 REST 的时候,发现要请求比如是 current_user 居然会定义多出一个 action,我当时就把 current_user 抽成了一个单独的 controller,哇哈哈,当时好幼稚。

comment 没有 live reloader 各种别扭啊...

#43 楼 @yedingding 可以改进一下,不然会少了很多欢乐的,不过改了就会很像 QQ 群,OYE

#40 楼 @fsword 我个人的观点不是不应该强调,而是要分开比较好。我看过很多讨论敏捷实践的人。他们讨论如何实践 TDD, 如何 pair,如果做 CI 更好,更方便更有效率。我觉得很好,我也照做,很有收获。如果要求首先要讨论出什么是敏捷,敏捷的本质什么?敏捷的概念是什么.... 这个太难... 我不是说不能讨论,而是要分开讨论...

#40 楼 @fsword 难不成不可以把 MVC 用 RESTful 组织风格?那 DHH 在写 Rails 的时候估计没想清楚。

#41 楼 @yedingding 其实我贴的那两个链接基本上已经很清晰了,论文讲了推导过程,反而容易绕进去。

一句话很难说的完整,简单说我常遇到的误解:我们常说的很多都是基于 http 协议的数据接口,而 REST 风格架构的关键并不在这里,它的特点是“先验知识”很少。比如 http 算是个 REST 的实现,它的对 agent 的要求很简单——理解 POST/GET/PUT/DELETE/... 即可,agent 在不理解具体的业务情况下依然能够演化出复杂的应用,而做到这一点是靠了所谓“超文本驱动“的思路,比如:浏览器访问一个网站,只有首页是用户输入的,拿到首页之后,可以根据获取的页面上的链接进一步驱动用户的行为,这个风格保证了标准客户端的产生,也让服务端可以自由演化,说实话,我很佩服这个思想,也是为此才较真。 刚才重新看了大家的 post,其实很多人应该都是理解 REST 的,比如 @hooopo@poshboytl ,欢迎纠正、补充

#45 楼 @poshboytl 这个本来是见仁见智,不过看到 @soloara 的几个帖子,让我觉得澄清概念也很重要,而且和现实的问题也有联系,比如你就不必纠结怎么设计 URL 更好,而是看你的框架服务的社区惯例,如果揪着 Rails 的惯用法不放,未免买椟还珠

#31 楼 @soloara grape 的作者就这样被你代表了。人家例子里又没有 delete 和 update 操作,为啥要用 delete 和 update?

注意,这里是创建资源,并不是更新资源:

post :update do
    authenticate!
    Tweet.create(
      :user => current_user,
      :text => params[:status]
    )
  end

#49 楼 @hooopo 嗯,这个问题可以问@poshboytl,他和作者一个公司的。我贴的代码里是 resouce。

#45 楼 @poshboytl 哪~ 多数人都是你所说的这个样子:没有搞清楚 what 和 why 之前就去研究 how,仅仅是因为大家都说这玩意好。为了 OO 而 OO,为了 TDD 而 TDD,为了 CI 而 CI,为了 agile 而 agile,为了 REST 而 REST,就是这样来的,急功近利的人儿啊。别理我,我跑题了。

You need to Sign in before reply, if you don't have an account, please Sign up first.