elixir-maru / maru

Elixir RESTful Framework
https://maru.readme.io
BSD 3-Clause "New" or "Revised" License
1.32k stars 84 forks source link

Support Maru::Entity #4

Closed teodor-pripoae closed 9 years ago

teodor-pripoae commented 9 years ago

Hi,

I created maru-entity as a clone of grape-entity, to help me serialize objects to json. Is there any way you can include support for it ?

Currently I'm doing like this to serialize objects inside a maru route:

get do
   users = User.all
   UserEntity.serialize(users) |> json
end

It would be nice to have a macro like:

get do
  users = User.all
  present users, with: UserEntity
end

Maybe add support to plug any serialization module which responds to serialize ?

falood commented 9 years ago

I'm following maru-entity and just working at this recently. I try to use Maru.Response protocol at master but I'm not sure that will be the final version. May be there's a better way to fork present of grape.

Any idea? Leave a comment please!

teodor-pripoae commented 9 years ago

I can see you started working on a way to return Map/List or strings and decide if you need to convert to json. This will remove the need for |> json part.

What I'm asking is a possibility to have a convenience macro for wrapping the Map/List into an entity, along with http information (similar with grape env) and also custom arguments.

This is possible in Maru.Entity as second argument to serialize, identical to Grape::Entity one. Example:

present users, with: UserEntity, my_custom_param: :here

# I think basically the ruby version it's doing something like this
# This is not taken from grape source code, it's a simplified version
def present(payload, options = {})
  entity_klass = options.delete(:with)

  if entity_klass.present?
    ext_options = env.merge(options)
    entity_klass.new(payload, ext_options).serializable_hash
  else
    payload.as_json # or do something else
  end
end

On a second look I think that grape actually looks for a represent class method on the entity class. I will check and update Maru.Entity if necessary.

falood commented 9 years ago

A demo version have been pushed to master via 04c9a6d, and you can use it like this. I won't close this issue now because I don't think this is the final version, waiting for your reply please!

PS. I think variable options should be Keyword instead of Map.

teodor-pripoae commented 9 years ago

It look good.

I prefer Map instead of Keyword for options since accessing maps by key is way faster than accessing keywords. Also, with Keyword it allows you to have duplicate keys and it will make lookup confusing inside entity.

I agree that rendering looks better using Keyword, but maybe we can convert it to Map before calling the entity ? What happens if somebody uses duplicate keys when calling present ?