4

As of Retrofit2 2.3.0 there seems to be no built in functionality to execute a JSON Patch Request (as defined in RFC 6902. Also, see http://jsonpatch.com/ for some examples). Using the available @PATCH annotation, the full blown object is sent with the request (as if I would send a PUT request, which is not what I'm looking for)

public interface MyService {

    @PATCH("example/{id}")
    Call<Example> patchExample(@Path("id") String id, @Body Example example);

}

After a first glance at the Retrofit documentation, there seems to be no clean and easy way to introduce a custom annotation (e.g. @JSONPATCH) to have my own implementation working.

The only related information I was able to find regarding this requirement was this experimental (as he calls it himself --> this is very experimental but it does the job currently) approach at https://medium.com/@andretietz/custom-annotations-with-retrofit-2-8701ca7ce102. I didn't give this example a try, but the complexity seems a little bit out of scale for this simple requirement.

Maybe I'm missing something and there is an easy solution for this?

wegenmic
  • 320
  • 1
  • 3
  • 13
  • Isn't the purpose of a patch request to just update part of the object on the server side? It has nothing to do with the client as far as I understand. As long as the client sends some data in a patch request, the server should accept it and update only the parts sent. If you send the full ``Example`` object then retrofit will of course send everything and the server has no choice but to update everything. Try and set only some properties in the object. Retrofit will only send non-null properties and the server will then only update those. Or am I confusing this? – Fred Nov 15 '17 at 10:02
  • In short, I would guess that most servers will accept the full blown Patch request. But there are some servers that only accept JSON Patch. The whole idea behind JSON Patch is to only send what you really need (i.e. what has changed). This approach is really useful if the resource you are manipulating is particularly large. When I change a single value, I don't need all the other non-null values to be transmitted as well, since they didn't change. – wegenmic Nov 15 '17 at 10:37
  • yes, but how would you expect this to work? Do you mean retrofit should detect what has changed and what not? Should you have a way to specify what changed? I mean, I for one think that the way retrofit handles this is the cleanest way you can have and most intuitive. If you just want to update part of an object, then you create that object with that part only and you send a patch request. – Fred Nov 16 '17 at 10:20
  • Retrofit handles a Patch request perfectly fine. But if you are forced to feed your API a Json Patch (see RFC 6902) instead of a "normal" Patch request, it will simply not work. So it's either adding my custom logic to enhance the existing Retrofit functionality (using for example a custom annotation) or using something else than Retrofit. Problems to find out what changed are already solved by others (see for example https://github.com/flipkart-incubator/zjsonpatch/). – wegenmic Nov 16 '17 at 12:11
  • yes I still don't get why you expect retrofit to handle this for you. Why can't you build a POJO that serializes to the Json patch? Why do you want to make this built into retrofit? – Fred Nov 16 '17 at 13:08
  • You mean something like https://gist.github.com/wegenmic/432f1243e8509b02a99c1c6a39d143a5? It will work, but if you have large and / or multiple services you want to use in your code, there will be a lot of boilerplate code. Well, if there is no simpler clean solution, I will probably stick with this idea. – wegenmic Nov 17 '17 at 08:11
  • Yes I meant exactly that. As for the boilerplate, I understand. Maybe some factories would help here. – Fred Nov 17 '17 at 08:28
  • GSON drops null values by default, so you don't send the full blown object, right? – Florian Walther Oct 27 '18 at 08:03

0 Answers0