intridea/grape — Issue #90: root object support
Author: evansj
Created: 2011-12-02 17:24:26+00:00
State: open

At Entity and/or Endpoint level, I'd like to be able to specify that an object or collection gets returned wrapped in an object. e.g. given this class:

```ruby
class UserManager < Grape::API
resource :users do
get do # /users
User.all
end

get ":id" do # /users/:id
User.find!(params[:id])
end
end
end
```

I'd like GET /users to return ```{ "users" => [ {"id": "1", ...}, {"id": "2", ...} ] }```, and GET /users/1 to return ```{ "user" => {"id": "1", ...} }```

At the moment I've got some code in a base Entity class:

```ruby
module Entities
class Base < Grape::Entity
attr :root

def serializable_hash(runtime_options = {})
root ? { root => super } : super
end
end
end
```

subclasses just supply a root method:

```ruby
module Entities
class User < Entities::Base
def root
options[:collection] ? "users" : "user"
end

# ...
end
end
```

This is obviously a bit clunky, but it works. How best to improve this though? A start would be to automatically work out the root key from the classname of the object. Maybe something like this?

```ruby
present User.all, :with => Entities::User, :root => true # -> work out the root key from the class of object
present User.all, :with => Entities::User, :root => "valid-users" # -> provide your own root key
```

Alternatively maybe it should go at the Endpoint level, so that anything returned would be wrapped in an object, even methods where you didn't use an Entity class?

I'd be happy to submit a patch, I just need to know which approach to use.