jsonapi-deserializable icon indicating copy to clipboard operation
jsonapi-deserializable copied to clipboard

block format for JSONAPI::Deserializable::Resource

Open fredmaremyob opened this issue 8 years ago • 9 comments

Hi

I am trying to use DeserializableResourceType.call() but receiving a {} return value.

I am not sure what the format for the blocks (type, attributes, relationship and id ) in the JSONAPI::Deserializable::Resource would be.

Thank you very much

fredmaremyob avatar Oct 27 '17 01:10 fredmaremyob

Fred,

I am having the same problem and have been struggling with it for hours.

In Rails (4.2.9) the received params hash has a top level :_jsonapi key and then the expected JSON:API :data key. The :_jsonapi key appears when the request's Content Type is application/vnd.api+json.

After some debugging I found that it works if if you call the deserializer as follows

DeserializableResourceType.call(params[:_jsonapi][:data])

This is a deserializer definition which gets all the received attributes

class DeserializableObservation < JSONAPI::Deserializable::Resource
  type
  id
  attributes
end

You can whitelist the attributes too.

class DeserializableObservation < JSONAPI::Deserializable::Resource
  type
  id
  attribute :code
  attribute :name
end

You can get an idea of the DSL syntax here https://github.com/jsonapi-rb/jsonapi-deserializable/tree/master/spec/resource/DSL

I tried with no luck to use deserializable_resource :observation

Regards, Héctor

hectorsq avatar Oct 31 '17 20:10 hectorsq

Thank you for the advice Héctor!

fredmaremyob avatar Oct 31 '17 21:10 fredmaremyob

This clearly needs proper docs, I agree.

In general, the idea is that one defines a custom deserializable resource as @hectorsq explained, using the DSL. In jsonapi-rails, there is a default deserializable resource that whitelists everything, and it is used when calling deserializable_resource :foo without further options.

@hectorsq could you expand on the following?

I tried with no luck to use deserializable_resource :observation

Also, the lib is currently tested against Rails 5 only, but I'd be happy to merge a PR to test it against more versions of rails.

beauby avatar Nov 01 '17 10:11 beauby

@beauby

When I add deserializable_resource :observationthe following is added to params

  "observation" => {
    "type" => nil
  }

One thing to notice is that the payload in the params hash is contained under a _jsonapi key

Here is a fragment:

{
  "_jsonapi" => {
    "data" => {
      "id" => "3B2F0580C0E84218151E8F94F2622196",
      "attributes" => {
        "code" => "apellido_paterno",
        "name" => "Apellido paterno",
        "loinc" => nil,
        "value" => "ACEVEDO"
      },
      "type" => "observations"
    }
  },
  "controller" => "medical_record/api/v1/observations",
  "action" => "update",
  "id" => "3B2F0580C0E84218151E8F94F2622196",
  "observation" => {
    "type" => nil
  }
}

hectorsq avatar Nov 01 '17 17:11 hectorsq

@beauby

I've done some research and noticed that the _jsonapi key is required.

I debugged my controller and the code inside the before_action block in deserializable_resource method is not executed. I will investigate if this is related to the Rails version.

hectorsq avatar Nov 01 '17 18:11 hectorsq

@hectorsq: Thinking about your issue, it is really weird that you do get an :observation param added at all if this line is not being executed as you mentioned. 🤔

beauby avatar Nov 02 '17 16:11 beauby

Anyone cal tell me the best alternative to jsonapi-rails as it clearly fails when it comes to deserialization. Serialization is also not production ready, it cannot properly serialize errors (it misses source key)?

Thanks

aamir-pk avatar Nov 29 '17 08:11 aamir-pk

Anyone cal tell me the best alternative to jsonapi-rails

Valid alternatives, with their own issues: jsonapi-serializers, jsonapi-resources.

as it clearly fails when it comes to deserialization.

Nothing is less clear. Would you mind elaborating?

Serialization is also not production ready, it cannot properly serialize errors (it misses source key)?

It is, it can and it doesn't.

Thanks

You're welcome.

beauby avatar Nov 29 '17 11:11 beauby

@beauby

I'm also getting type => nil from the deserializer process.

I think the reason might be that the jsonapi parser calls .with_indifferent_access, so inside deserializable_resource you can access for instance controller.params[:_jsonapi][:data], however, after calling controller.params[:_jsonapi].to_unsafe_hash, you seem to lose the ability to use symbols to access keys, so below in that method, when you do resource = klass.new(hash[:data]), hash[:data] is nil but you get the correct data if you do hash['data'].

Could you please tell me if I'm missing anything here? Thank you!

lemattma avatar Sep 26 '18 05:09 lemattma