Daniel Doubrovkine bio photo

Daniel Doubrovkine

aka dB., CTO at artsy.net, fun at playplay.io, NYC

Email Twitter LinkedIn Github

I’m very excited to Release Grape 0.4.0 today. Again, thanks to the 10 (!) contributors to this release.

Is this a solid release? You bet. I’ve upgraded our largest API project at artsy.net to Grape 0.4.0 and all of the 1870 API specs have passed.

The complete CHANGELOG is here. There’re a few backwards incompatible changes that you might want to check out while you’re upgrading.

JSON and XML Formatter Changes

Until the 0.4.0 release Grape took a pragmatic approach to JSON response and request data. It was also incorrect.

If your API returned a an Object, it was translated to JSON via to_json or a MultiJson.dump call. This worked well for both Hash and Array, meanwhile Grape left objects of type String alone. This friendly method ensured that you could translate an object into a String, skipping all the hard work Grape’s formatter would otherwise have to do. Similarly, Grape tried to be helpful by ignoring any data that couldn’t be parsed into a hash and therefore retrieved via a call to params from a PUT or POST.

I have fixed this in @6fa8f59, released with Grape 0.4.0, and it’s now possible to return proper JSON representations of NilClass or String, as well as to parse any valid JSON, such as Array. This means that if your API implementation returned a String or a nil, the output will be different.

get "/" do
 "example"
end
# Grape 0.3.x
"example"

# Grape 0.4.0
"\"example\""
get "/" do
 nil
end
# Grape 0.3.x
""

# Grape 0.4.0
"null"

You can monkey-patch back the old behavior as follows.

module Grape
 module Formatter
   module Json
     class << self
       def call(object, env)
         return object if ! object || object.is_a?(String)
         return object.to_json if object.respond_to?(:to_json)
         raise Grape::Exceptions::InvalidFormatter.new(object.class, 'json')
       end
     end
   end
 end
end

Similar changes apply to the XML formatter.

Reading Input

With the above changes its now possible to read JSON input that’s not a hash. This was reported as a bug in #347. Hash parameters continue to be merged into params, while everything else is now available in env[‘api.request.body’], you don’t have to parse env[‘rack.input’] again, a notable performance optimization.

Default Log Format

Somewhere in version 0.3.2 the default logger format was inadvertently changed to be something like this.

I, [2013-02-27T18:39:20.352350 #85986]  INFO -- : one line
I, [2013-02-27T18:39:20.363543 #85986]  INFO -- : two lines

This was a side-effect of requiring all of ActiveSupport, reported and fixed in #353. The logger is now back to be its undecorated version without all those timestamps, levels or process IDs.

If you want the above behavior, require active_support/all.