kamikat / moshi-jsonapi

JSON API v1.0 Specification in Moshi.
MIT License
156 stars 34 forks source link

Array deserialization/serialization #55

Closed skliba closed 7 years ago

skliba commented 7 years ago

Why do array objects need to know that they belong in an array?

We've encountered a weird issue in your lib, our API uses JSON API specification in order to send us a list of objects e.g. Body:

{  
   "data":[  
      {  
         "type":"person",
         "id":"1",
         "attributes":{  
            "name":"James",
            "surname":"Jones"
         }
      },
      {  
         "type":"person",
         "id":"2",
         "attributes":{  
            "name":"James1",
            "surname":"Jones1"
         }
      }
   ]
}

We deserialize the response into a list of objects. Afterwards we're doing a PUT call to our API with only one of those objects we get in a list.

The library serializes the object as an array:

{  
   "data":[  
      {  
         "type":"person",
         "id":"1",
         "attributes":{  
            "name":"James",
            "surname":"Jones"
         }
      }
   ]
}

Once we try to send one of those objects from the list back to the API it gets sent as an array because of the flag inside the Document class called arrayFlag. Since the object we're looking at has come in an array from the API it has that flag set to true. Basically we couldn't get to that flag in any way other than setting the context to null

personObject.setContext(null);

or simply instantiating a new object

Person newPersonObject = new Person("name", "surname");
newPersonObject.setId(personObject.getId());

That way the Document object inside our model gets reset and the flag is back to false which results in serialization to complete successfully and the object is on its own, that is, not wrapped in an array.

{  
   "data":{  
      "type":"person",
      "id":"1",
      "attributes":{  
         "name":"James",
         "surname":"Jones"
      }
   }
}

According to the documentation PATCH/PUT API calls should send only one object. Can this be fixed by either separating serialization/deserialization or allowing the modification of arrayFlag?

kamikat commented 7 years ago

Thanks for opening this issue. A change in Document has been upload to the repository. This change deserializes document to either ObjectDocument<T> or ArrayDocument<T>. There is no semantic ambiguity now 🎉

(More tests should be added before we can make a release. Until then, you can try the snapshot build)