Serialize payload into a grape entity on post/put

645 Views Asked by At

Is there a way with Grape & Grape-Entity to automatically serialize data into an entity? It seems like all of the examples use params[:var] (from: https://github.com/intridea/grape)

desc "Create a status."
params do
  requires :status, type: String, desc: "Your status."
end
post do
  authenticate!
  Status.create!({
    user: current_user,
    text: params[:status]
  })
end

When the posted entity is more complex (lets say a new person (firstname, lastname, address, etc), Is there a way to automatically have it turns into the entity that API represents? Looking for some kind of usage like this:

post do
  authenticate!
  entity.first_name
  entity.last_name
end
1

There are 1 best solutions below

0
On

Is your entity an ActiveRecord model? If so, maybe MyModel.new(params)? Or better, you can only allow declared parameters like this: MyModel.new(declared(params)). See the doc here.

Ruby has lots of power with meta-programming to allow you to do what you want yourself, less painfully, with things like meta-programming where you could loop over the params and set the entity's fields. However, what you're wanting to do is actually complex, which is why there's no general purpose solution for it. Imagine if you had deeply embedded associations in your entity. I think the typical recommendation is to embrace the fact that what you're given via an API (and what you give back) is a representation of a thing, not the thing itself. Following this, if what's being passed in already represents an existing thing, perhaps that thing can be represented by a single ID? If your API takes an ID, then you just look the thing up. This is the advice given when using things like Sidekiq: when you want to process some data in the database later, you capture the ID of the database record, and not all the data itself. This has advantages in case the data changes in the meantime, etc, but the point here is that you might benefit from having your API accept a pointer to something you can load.

I'd say the best use case for what you want is when your entity is complex, which you said is your case. Consider making your entity less complex.


As a stretch: you might want to take a look at grape-entity, although I think it's kind of the inverse of what you want, since I think (I haven't used it myself, and the documentation isn't very clear to me about its high-level purpose) it's meant for working with your entities for the response.