Rails Grape 返回 JSON 格式太不灵活

rbprocareer · 2014年08月25日 · 最后由 birbird 回复于 2015年08月01日 · 6882 次阅读

我期望返回以下格式的数据:

{
    code: 1000,
    msg: "OK",
    data: {
        // normal data goes here if exists
    }
}

present 具体 Entity 时挺好用的,但涉及到内嵌结构的时候就不灵了

// ok
present :items, Book.all, with: Entities::Book
// does not work
resources :books do
    get do
        present :code, 1000
        present :msg, "OK"
        present :data do
            present :items, Book.all, with: Entities::Book
        end
    end
end

本来手动组织这样的结构是微不足道的,引入框架后反而这个过程变得异常复杂和不灵活!~ 请问有什么替代方法吗?

直接在 data 中返回一个你定义的 hash 就行了。

貌似这段代码也不行。

# does not work
present :data,  present(:items, Book.all, with: Entities::Book)

建议写进 entity 里。本来 json 的结构 grape 都是交给 grape-entity 负责的。换用 jbuilder 结果是同一回事。

#2 楼 @hammer 那为什么不直接用 rails

#4 楼 @yukihiro_matz 这需要问 lz 了 用 grape 是为了跟 web 分离

直接定义一个 format 格式的函数 helper 也可以。这样也统一了返回格式。

def format(data, msg="ok", code=200)
  {data: data, msg: msg, code: code}
end
7 楼 已删除

grape-jbuilder +1

楼主你用的什么 Entity,grape 的 Entity 非常灵活方便啊 内嵌复用什么的妥妥的

module Entities
  class ProductService < Grape::Entity
    expose :name
    expose :description
    expose :resource_category, using: ::Entities::ResourceCategory
  end
end

grape-entity

@losingle 涨姿势了👍,原来 formatter 可以这么用。grape 作者也没告诉我啊😂

另外提供另一个思路作为参考: 使用 Entity#represent

@hammer 1. grape-jbuilder 看起来有点糟糕。2. grape 与 web 分离,做成两个项目,ActiveRecord 怎么复用?

@yukihiro_matz rails 太重了,似乎不是为 web service 设计的,我也不想把 web 代码和接口代码交织在一起,接口可能需要 token 认证等等,web 代码可能不用。另外两者的错误处理也不同。

@hardywu 嗯,不行。查看代码发现 present 并不是直接返回一个 Hash, 而是做了一些副作用的事,把结果赋值给 @bodyhttps://github.com/intridea/grape/blob/a0447887b46902c392973aac6e7623f6fd63fd5d/lib/grape/dsl/inside_route.rb#L169.

#14 楼 @rbprocareer 加 Grape 在 Gemfile 正是为了复用 ActiveRecord 要不用可以直接上 sinatra、pardino 这些了

@leopku 用 sinatra 就得把 ActiveRecord 重写一遍简直不能忍受啊,有没有 best practice?

#18 楼 @rbprocareer , AR 可以自己独立使用。不管是在 sinatra 还是在别的什么 framework 里。 这里是我自写的一个 rails-like web framework, 里面就直接用的 AR. https://github.com/suffering/learnmvc/blob/master/srbmvc/lib/srbmvc.rb#L34 做这样的简单设置后,就可以像是在 rails 里一样使用 AR 了。

嗯,我知道 AR 可以脱离 rails 使用,但怎么做到 DRY? @losingle @suffering

哪些东西REPEAT YOURSLEF了?或者说哪些东西在使用 AR 时导致代码一再重复了? 避免 grape 重复代码,可以参考 ruby-china 的源码:https://github.com/ruby-china/ruby-china/tree/master/app/grape 另外,rails 中 grape 的使用与 ORM 无关,资料查询与处理的方法都在 model 中写好,grape 中直接用就可以了。

#19 楼 @losingle 我的习惯是直接在 Rails 中直接加上 Grape,API 和 网站 (Rails) 代码共享 ORM 的迭代。 不是什么 best practice。 个人看法是项目没大到一定程度,没必要把 Grape 单拆分出来。

@suffering 当将 web 代码和 api 代码分成两个项目,部署成两个服务后,AR 代码要么重写一遍,要么一个项目写好后,简单粗暴地 copy & paste 到另一个项目,要么做成一个 gem 啥的进行共享,使用 bundler 导入。。。视乎都不是好办法

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