rabl
rabl copied to clipboard
Inconsistent JSON/XML output, missing RABL config option to collapse nodes to array consistently
The problem appears to be an inconsistency between XML and JSON output and that there is currently no config option that allows app developers to collapse nodes like {"bundles"=>[{:bundle => {...}}]}
(this happens for :json response format) or {"bundles"=>"bundle"=>[{...}]}
(this happens for :xml response format) to {"bundles"=>[{...}, {...}]}
The particular context is to create a generic application.rabl
layout that requires this structure, e.g. {"bundles"=>[{...}, {...}], "code": "1", "message": "OK"}
# application.rabl
# Constructs a response like:
# {"bundles"=>[{...}, {...}], "code": "1", "message": "OK"}
#
object @response
node do
case response.content_type
when Mime::JSON
# Since RABL converts collections to {"bundles"=>[{:bundle => {...}}]}
# we need to apply this ugly hack to make it look such as
# {"bundles"=>[{...}, {...}]}
res = Yajl::Parser.parse(content_for(:layout))
if res.try(:[], controller_name).is_a?(Array)
res[controller_name] = res[controller_name].map {|b| b["bundle"]}
end
res
when Mime::XML
# Again RABL gives us elements like <bundles><bundle></bundle></bundles>
# that is parsed to hash as {"bundles"=>"bundle"=>[{...}]} which
# makes us this this hack, which transforms it to
# {"bundles"=>[{...}, {...}]}
res = Nori.new(:parser => :nokogiri, :advanced_typecasting => false).parse(content_for(:layout))
if res.try(:[], controller_name).try(:[], controller_name.singularize)
res[controller_name] = res[controller_name][controller_name.singularize]
end
res
end
end
node :code do |response|
response.code
end
node :message do
response.message || [Api::Code.get_message(self.code)]
end
My index.rabl
looks like this:
collection @bundles, :root => :bundles
extends "api/v2/bundles/show"
And the show.rabl
like this:
object @bundle
attributes :id, :name, :status, :bundle_type, :begin_at, :end_at, :updated_at, :created_at
My config looks like this:
Rabl.configure do |config|
config.include_json_root = true
config.include_xml_root = false
config.include_child_root = false
config.xml_options = {:skip_types => true, :skip_instruct => true, :indent => 0, :dasherize => false}
end
This is related to Stack Overflow question Parsing XML to hash with RABL and Does RABL's JSON output not conform to standard? Can it?