最近在做基于 jsonapi 的设计,本来的设想倒是挺不错,但是由于客户可能有工厂较大批量的存在,导致数据可能有批量操作的发生,尤其是在create
操作上。
想问下大家,有没有什么较好的解决办法?
jsonapi 里的 post 操作一次仅允许提交一个数据。我的想法是根据需要批量操作的动作创建单独的控制器,比如creates
,然后定义type
和value
等字段,我在控制器里解析操作。插入对应的表中。
但是感觉有点麻烦,不知道还有没有好的办法?
我是这么做的:
写了一个名叫create_multiple
的 action
参数格式是{model_name: [{ arrtibutes_hash }]}
然后使用 bulk_insert 进行批量插入
可以做,也不用打破规则。你可以建立一个 batch model 来处理,其中的一个 attribute 接受 array。如果 array 其中一个失败就全部回滚并报错。
死抠 REST 的话,就如楼上几位讲的一样,把 batch model 也做为一个资源。我的观点是,REST 保持了接口的组合性,但是对于特定的要求还是 RPC 更好。
这样想一下,batch create 的时候如何控制超时?如果有冲突的数据需要先处理哪一个?如果出错了如何让用户知道是哪个数据出错?
JSON API 原本是有一个 bulk extension 的,实际上 JSON API 是有一个扩展系统的设计的,而 bulk 是其中之一:https://github.com/json-api/json-api/blob/9c7a03dbc37f80f6ca81b16d444c960e96dd7a57/extensions/bulk/index.md
当然,标准对其做了规范是一方面,具体的实现有没有做那就要单说了。
然而这个扩展系统一直以来都是试验性质的,并且目前已经被 deprecated 了。照官方的说法,一个新的扩展系统正在开发中,希望它能长久稳定吧。
params :actor do
requires :name, type: String
requires :character, type: String
requires :movie_id, type: Integer
end
params do
optional :actor, type: Hash do
use :actor
end
optional :actors, type: Array[Hash] do
use :actor
end
at_least_one_of :actor, :actors
end
post '/' do
@actors = unless params[:actors].blank?
Actor.create(params[:actors])
else
[Actor.create(params[:actor])]
end
end
Model.create([
{name: "John Doe", character: "The Hobbit", movie_id: 1},
{name: "Christian Bale", character: "Batman", movie_id: 2}
])