https://gist.github.com/mrbongiolo/bbabbda0bbd8f57769a0
I receive a simple customer hash like that:
{ provider: 'local', name: 'Wilhelm Reich', email: '[email protected]' }
And I need to return this:
{
"customer": {
"id": "SUCH_HASH_MUCH_IDNESS",
"token": "MY_API_TOKEN",
"name": "Wilhelm Reich",
"email": "[email protected]"
}
}
I receive a simple customer hash like that:
{ provider: 'remote', code: 'the_remote_api_auth_code' }
And I need to return this:
{
"customer": {
"id": "ANOTHER_HASHED_ID",
"token": "AND_ANOTHER_TOKEN",
"name": "Sigmund Freud",
"email": "[email protected]"
}
}
This could be accomplished by calling a custom Decorator on the valid block when running the operation.
Something like that:
run Api::Customer::Create do |op|
return render json: Api::CustomerDecorator.new( op.model ).to_json
end
By doing this I could remove the Decorator and Representer from the operation, actually I (think) could still leave Representer in to enable parsing from different sources.
I tried this schema using Representer instead of Decorator, but was getting some weird results and errors, mostly because if I set self.representation_wrap = :customer
the parsing expects to receive the data as: customer: {}
. And when I sent in data like that the parser returned some errors, I guess it happens because Representer has to do this params[:comment] = request.body
as shown here: http://trailblazerb.org/gems/operation/controller.html#respond.
My main "concern" with Representer is that it expects the same document to be used for parsing and rendering, that's ok for most cases, but it seems to become a mess when that's not the case.
I had a case where I could redeem a voucher for a resource, something like:
# POST /vouchers/redeem { voucher: 'SUCH_CODE_MUCH_DISCOUNT', resource_id: 'CRAZY_ID_HERE' }
# The Voucher::Redeem operation would check it and if everthing was OK apply the voucher to the resource
# The valid response was the updated :resource
As shown above, I can "easily" set the response by calling the desired Decorator on the controller, but I was thinking if it wouldn't be better to add this kind of behaviour to the Operation, so that we can call operation.to_json
, operation.to_xml
or operation.to_whatever_crazy_format_i_need
.
It's a way to set on the Operation what it expects to receive and what it will output.
I'm just trying to understand and find the best way to handle those situations, maybe an Operation shouldn't care about the "result". It will just receive some data, do stuff on it, and I can decide what to do with it.
Cool, thanks for this! I agree that if you have different ins and outs, you don't wanna use the same representer, absolutely not!
@timoschilling and I had this idea:
That way, it's up to the user to configure it should it be different behaviour than the default (use same for both).