json_api_client icon indicating copy to clipboard operation
json_api_client copied to clipboard

json_api_client overriding the type given by the server!

Open krainboltgreene opened this issue 7 years ago • 7 comments

The server is responding with type: 'user', but my remote class is rewriting that to the name of the class. Why would you do this?

krainboltgreene avatar Mar 16 '17 17:03 krainboltgreene

Can you go into a little bit more detail? I don't see the type being overwritten anywhere in the code, so i'm not sure what you mean?

gaorlov avatar Mar 20 '19 15:03 gaorlov

@gaorlov I guess @krainboltgreene has the same problem as me. My resource on a server has a type attribute. Here is a response from my server. Pay attention that on the top level "type": "securities" that reflects the resource type, but "type": "stock" inside attributes reflects internal resource attribute.

{
  "data": [
    {
      "id": "471596",
      "type": "securities",
      "attributes": {
        "type": "stock",
        "sa_id": 146,
        "sa_slug": "aapl",
        "primary_retriever_klass_name": "fin_api_puller",
        "default_retriever_klass_name": "fin_api_puller",
        "history_retriever_klass_name": "xignite_quote_history_puller",
        "populate_quotes": null
      }
    }
  ]
}

When I try to update this resource json_api_client sends {"id"=>"37", "type"=>"stock", "attributes"=>{"populate_quotes"=>true}}. Type must be securities but it was taken from attributes (stock). I think we can easily fix it in JsonApiClient::Resource#as_json_api by taking self.class.type instead of attributes.type.

bguban avatar Jun 22 '22 14:06 bguban

Looks like it's not so easy. type is added into read_only_attributes and doesn't appear in changed. @gaorlov what do you think about separating resource type and type from attributes? I'm almost sure that I'm not the first person with such a problem and I guess there are some caveats to treating those types separately.

bguban avatar Jun 22 '22 15:06 bguban

@bguban I guess my question here is: should we apply this to all the special attributes (id, name, links, meta, relationships), or should we assert that these are reserved attribute names and to surface an error message when the users try to overwrite them?

gaorlov avatar Jun 22 '22 18:06 gaorlov

JSON API specification doesn't restrict of using id, name, links, meta, relationships attributes. So would be nice to have the ability to separate them. Otherwise json_api_client becomes useless in the cases I showed above.

bguban avatar Jun 23 '22 08:06 bguban

@bguban it does specify that id and type have to be strings. I think for type it's reasonably straightforward to move it into the class, but for the rest of them, I am curious how would you disambiguate between a links attribute and the system links property?

gaorlov avatar Jun 28 '22 16:06 gaorlov

Looks like I was wrong about the specification https://jsonapi.org/format/#document-resource-object-fields

Fields A resource object’s attributes and its relationships are collectively called its “fields”. Fields for a resource object MUST share a common namespace with each other and with type and id. In other words, a resource can not have an attribute and relationship with the same name, nor can it have an attribute or relationship named type or id.

That means that the library follows the spec, but would be nice to have the ability to access attributes directly. For the case described above it can be like:

security.type # => 'securities'
security.attrs.type # => 'stock'

security.attrs.type = 'fund'
# should not change top-level type
security.type # => 'securities'

bguban avatar Jun 28 '22 17:06 bguban