Ruby API

Choose the route system -- Sinatra likes or Rails likes?

现在多数的时候会选择RESTful的api,sintra和rails都是RESTful的,但风格却大不相同。

  1. Rails的路由其实是Resource-Oriented
    每个uri其实对应一个resource,controller的方法对应在此基础上的操作。
    换句话说,非常契合RESTful(uri定义资源,http method 定义操作)。

    并且,rails讲各种资源很好的分开了。
    换句话说rails帮你做了很多事,代码更好管理。

  2. 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

  1. 使用情景
    1. 简单应用
    2. web应用 + 简单API(见上一段也已经说明了)
    3. 单独挂在在rails下,性能好
  2. 简单,直接。文档全,流行。很多问题都能在网上找到解决方案。很多基于grape的gem
  3. 好用的API DSL
  4. 分离
    1. 单独文件
    2. 跟rails分离
      选择rails,相当于告别了很多rails的东西。
      1. 结构上来说,几乎告别了Resource-Oriented,当然也可以使用grape-entity。再把去掉的这些东西加回来。
      2. 功能上,error handling, logging, middleware stack 都和rails分离了

rocket_pants

  1. 没有views层
    需要在model中定义serializable_hash来expose数据。
  2. 不单独分出API文件,直接在controller里面写。
  3. 方便的写API DSL。

acts_as_api

根据文档,这个gem,主要做的工作是,数据的显示(data represtion),并这部分功能被放到model。

换句话说,只是为API中数据显示提供了一些机制。

个人觉得,数据如何展示不应该是model的职责。但,其实放到model层也有一定的好处。这个就仁者见仁,智者见智了。

rocket_pants

大体来说可以很好的为api服务,并且和rails配合更好。

  1. 没有views层
    需要在model中定义serializable_hash来expose数据。

  2. 不单独分出API文件,直接在controller里面写

      class ApplicationController < RocketPants::Base
      end
    
      class UsersController < ApplicationController
        def index
          expose ....
        end
      end
    
  3. 可以很方便的写API。
    比如
    Registering / Dealing with Errors
    Built-in Header Metadata Support
    version ....

versionist && api-versions

主要是为API提供了版本机制。
versionist的不同版本间需要copy,past,这点比较不能接受。

而api-versions通过继承,共享代码,所以推荐versionist。

最后

还是要根据项目的需求,具体选择API。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Awesome Ruby Toolbox Awesome A collection of awesome Ruby...
    debbbbie阅读 2,934评论 0 3
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,261评论 4 61
  • 我很少看动漫,从前,甚至是排斥的,可能是因为基因里缺少叫做热血的成分。 听说《蜂蜜与四叶草》有好多年了,直到最近才...
    Deardeer迷路的麋鹿阅读 385评论 0 0
  • 一排排的杨树林,在春天满眼绿色的季节里,有点显得苍凉。 五点的日落,虽然不够浓烈,却依然有橙黄的光线。暖暖的。 带...
    摄影师李瑕Melissa阅读 335评论 0 1
  • 提起孤独,许多人都有种恐惧感。其实,生活里任何人都要面对,谁也无法真正意义上能够躲开孤独的。 孤独...
    易梦的原野阅读 617评论 2 7