Gem jbuilder vs active_model_serializers

ericguo · 2016年12月26日 · 最后由 easonlovewan 回复于 2017年01月11日 · 6072 次阅读

今天看到 @huacnlee 在最新的 homeland 上计划将 active_model_serializers 替换成 jbuilder ,除了这俩个 gem,我之前也用过一段时间 Grape,总的感觉是 active_model_serializers 耍起来还是要比 jbuilder 帅太多,比较符合 Ruby 的气质

想和大家讨论下如果下一个项目,你会用还是 jbuilder 还是 active_model_serializers?

jbuilder 是 Rails 官方维护的,还有 DHH 参与,Basecamp 也在用,改用它能更快接上 Rails 最新版本

推崇主厨精选的思路我也赞同,不过我用过一点 grape,个人感觉 grape 在实现 api server 的时候,确实有很多比较好的实践,比如他的 api 请求参数限制方式;grape entity 的封装 复用,挺灵活,值得学习。 不知道 jbuilder 和 AMS 在同一种对象,不同输出格式的情景里,是不是能做到 grape entity 的这种方式。

其实在我看来 active_modal_serializer 和 jbuilder 都没什么大问题,只是各自表现方式不同,但 jbuilder 能随着 Rails 组的管理获得更快的新版本支持,为何不用呢?

当然 jbuilder 我也是第一次用,不知道会不会有其他的问题,只是目前看起来没什么明显的问题,也挺好用的,从 active_modal_serializer 已有的代码重构也几下就弄好了。

哦,jbuilder 内建类似 ActionView 那种 fragment_cache 的哦,这点用起来很舒服。

而 active_modal_serializer 的 cache 写法到现在我还没搞太明白,好像是有点小问题没搞透

#5 楼 @huacnlee 现在看 AMS 的文档,它的 cache 似乎还是有点问题的。

active_modal_serializer 我每次都是边用边吐槽,感觉维护也很乱

用 jbuilder 的话,我建议可以试一下 jb

#7 楼 @numbcoder ams的维护 bf4非常勤勉,实际上远远超出了jbuilder的几位维护者。。

jbuilder 在 Rails 兼容性方面安心很多,毕竟是亲儿子

#8 楼 @ericguo 抽象增加要做的工作就多。

用过 jbuilder 也用过 grape 现在正在用直接用 controller 做 api,不过直观感受是以前用 jbuilder 做 API,随着版本的升级业务的扩展,文件变得越来越多,难以维护 (可能是因为能力问题)

#11 楼 @Rei 这篇文章我看过,从 gem 作者的角度,这样说一点问题没有,但是如果从 web 应用开发者角度,我认为,有现成的 gem,质量过得去还是要用,啥都自己造轮子何必要用 Rails 呢?。。。

#13 楼 @ericguo 如果只做 ping 服务器,确实没必要用 Rails。Rails 自带了构建 web 应用的很多组件,如果满足需求,就没必要增加依赖。

换个组件增加抽象的愉快感很可能是短期的,长期看就是维护和沟通成本的负担。

#3 楼 @huacnlee active_modal_serializer 0.10.4 已经不依赖于 json 了,不管 1.8 还是 2.0

#15 楼 @ericguo 太慢了,我都重构完了

@realwol 同意。Grape 自带参数的 validator,用起来比较省心,而且作为 API 的话,比较方便地描述参数的限制,对客户端开发者来讲也是很赞的。

ActionController::API 还是没有类似 Grape 的参数 validator 和 声明机制,不晓得 @huacnlee 平时是如何使用的? 目前看 rails-api 没有对此支持的计划:https://github.com/rails-api/rails-api/issues/216

觉得 jb 更好,那些 dsl 没必要...

#7 楼 @numbcoder 如果只是单纯输出 json,不依赖 gem 直接用 rails 的 json.ruby 模板就行了。。

# views/**/*.json.ruby
obj = {
  title: @post.title
}
if user.admin?
  obj[:admin] = true
end
obj.to_json
# *_controller.rb
render json: render_to_string('**/*.json.ruby'), content_type: 'application/json'

#19 楼 @saiga Real World 里面不是这么简单的,关联数据(甚至几层的情况)需要 cache 的

#20 楼 @huacnlee 是的,所以我加上只考虑单纯输出 json,因为和 jb 的写法太像了😂

美学前端肛了之后 以后再也不敢用 ams..

#20 楼 @huacnlee 缓存 cache(...) { ... } 就好了,也不关模板的事

#23 楼 @luikore 有一些细节的,例如 Views Digest,自己搞是可以,但最后都从头实现了

另外上次回复的时候我没注意看,原来 #19 楼 @saiga 是写的 *.json.ruby 的模版文件,这样其实也差不多和 jbuilder 一样了

最近在尝试一种新方案:重写 as_json 的 json_options,根据业务需求去自定义它的 json 结构如下:

self.json_options = {
    only: [:xxx],
    methods: [:xxx],
    include: {
      xxx: {......}
    }
  }

然后 controller 层 index 如下:

render json: {users: @users.as_json}

如果特殊的接口可能需要自定义一些 json 格式

class_attribute :show_json_option
self.show_json_options = {
    only: [:xxx],
    methods: [:xxx],
    include: {
      xxx: {......}
    }
  }

然后 controller 层 index 如下:

render json: @user.as_json(User.show_json_option)

把重 model 发挥到极致😂

#28 楼 @huacnlee 还好吧,每个 model 基本只定义了 index_json 和 show_json,目前没有遇到维护上的难题😅

#29 楼 @easonlovewan 比如 API 1.0 和 API 2.0 结构大调整怎么办,jbuilder 远比 其他方案简单清晰的多

#30 楼 @hbin 目前考虑的只能在原有的基础上进行改动

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