Choose the route system -- Sinatra likes or Rails likes?
现在多数的时候会选择RESTful的api,sintra和rails都是RESTful的,但风格却大不相同。
-
Rails的路由其实是Resource-Oriented
每个uri其实对应一个resource,controller的方法对应在此基础上的操作。
换句话说,非常契合RESTful(uri定义资源,http method 定义操作)。并且,rails讲各种资源很好的分开了。
换句话说rails帮你做了很多事,代码更好管理。 -
Sinatra 是 in terms of HTTP requests/responses,是RESTful like
特点是灵活、直观,简单。但很多事情要自己做。
一般来讲,比较简单的应用,Sinatra这样的路由系统比较合适。
但一旦项目大起来,你会发现,Sinatra项目会越来越像Rails,要么会越来越难以维护。
Why grape + rails?
grape的路由系统其实更像Sinatra,既然选择了rails,那么一定程度上说明,并不喜欢Sinatra的风格。
但为什么很多项目都会选择rails + grape的架构呢?
在我实际接触过的项目中,大体都是这样的流程。
先是有rails的web项目,项目写到一定程度后,需要提供一套(公共的)API,而且这套API相对原有的web应用,要简单的多。
比如使用Grape的Artsy.net(域名真相asp.net啊。。。)就是这种情况。
他们的web端用rails(MVC)+ backbone,API使用grape
从他们的文档来看,API操作并不复杂。
But why?
我们做这样一个假设,如果不引入grape,会是一个什么样的情况?
那么我们controller中的某些方法,会做两件事,一,为web提供服务,二,为API提供服务。
任何情况下,一个方法,做两件事,都是很糟糕的。
那么我们给api提供单独的api-controller,这样的话会有很多api-controller,而且多数的api-controller会只有很少的代码。
那么还不如把这些api都放在一个文件里,而grape恰恰很好的解决了这两个问题。
所以,有web项目,有需要提供(公共的)api,而且,这个API有比较简单、比较少。
用grape恰好把这些API同原有的web项目分离,并且提供很多很好用的DSL。所以这个时候grape是最好的选择。
但,如果API越来越复杂了呢?一般会引入grape-entity,
你会惊喜的发现,引入了grape-entity,一个Model有了对应的entity文件,以及对应的API文件,你会发现,grape越来越像rails了。。。
Grape
- 使用情景
- 简单应用
- web应用 + 简单API(见上一段也已经说明了)
- 单独挂在在rails下,性能好
- 简单,直接。文档全,流行。很多问题都能在网上找到解决方案。很多基于grape的gem
- 好用的API DSL
- 分离
- 单独文件
- 跟rails分离
选择rails,相当于告别了很多rails的东西。- 结构上来说,几乎告别了Resource-Oriented,当然也可以使用grape-entity。再把去掉的这些东西加回来。
- 功能上,error handling, logging, middleware stack 都和rails分离了
rocket_pants
- 没有views层
需要在model中定义serializable_hash来expose数据。 - 不单独分出API文件,直接在controller里面写。
- 方便的写API DSL。
acts_as_api
根据文档,这个gem,主要做的工作是,数据的显示(data represtion),并这部分功能被放到model。
换句话说,只是为API中数据显示提供了一些机制。
个人觉得,数据如何展示不应该是model的职责。但,其实放到model层也有一定的好处。这个就仁者见仁,智者见智了。
rocket_pants
大体来说可以很好的为api服务,并且和rails配合更好。
没有views层
需要在model中定义serializable_hash来expose数据。-
不单独分出API文件,直接在controller里面写
class ApplicationController < RocketPants::Base end class UsersController < ApplicationController def index expose .... end end
可以很方便的写API。
比如
Registering / Dealing with Errors,
Built-in Header Metadata Support,
version ....
versionist && api-versions
主要是为API提供了版本机制。
versionist的不同版本间需要copy,past,这点比较不能接受。
而api-versions通过继承,共享代码,所以推荐versionist。
最后
还是要根据项目的需求,具体选择API。