anthonymonori anthonymonori - 1 year ago 81
HTTP Question

How to get a HEAD of a Retrofit call from an api endpoint that requires field in the request body?

I am trying to examine the headers of a response from an API call made via Retrofit 2.0.2 before actually downloading the content.

My API interface looks like the following:

@Headers({"Accept: application/json", "Origin:"})
Call<Void> getProfileHeaders(@Field("puids") String puid);

Please note that the API call requires me to specify in the body a field called
list of UUIDs in order to return a response.

If I would like to download the data without examining the headers first, I would just call an interface like this:

@Headers({"Accept: application/json", "Origin:"})
Call<String> getProfile(@Field("puids") String puid);

Now the issue is that when I try to use the
endpoint, I get the following RuntimeException:

java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)

In order to use the @Field parameters (as I suppose a POST method would normally would do if required), I would have to explicitly specify that I use
, but I can't make a
call with that.

I am a bit puzzled how could I achieve what I want and what am I missing?

Basically I would like to know how can I examine a retrofit call's response headers before downloading the actual body, of an API endpoint that requires field parameters?


Answer Source

Ok, I just realized that my confusion originates from a couple of misunderstandings:

  1. @HEAD is an HTTP method to usually verify the hyperlinks validity and the server's response to a GET call. It does not work with POST request and it is theoretically incorrect.

Taken from RFC2616 of the HTTP/1.1 definitions:

The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification.

The response to a HEAD request MAY be cacheable in the sense that the information contained in the response MAY be used to update a previously cached entity from that resource. If the new field values indicate that the cached entity differs from the current entity (as would be indicated by a change in Content-Length, Content-MD5, ETag or Last-Modified), then the cache MUST treat the cache entry as stale.

  1. When making a POST request by definition we already calculated the response server-side and taken the time to download the body in consideration.

One of the function's of the POST method, as defined in RFC2616 is:

  • Providing a block of data, such as the result of submitting a form, to a data-handling process;

Hence verifying the header in order not do download the body beats the purpose of this.

As mentioned by @Radek above, using interceptors on GET request to modify and/or examine requests on the fly would do the work, but at that point we could also initiate a HEAD method request.

The solution to this problem would be to better align to the standard definitions defined in RFC2616 by making changes on the server-side to instead of returning block of raw data as a POST response, make it to return a resource that would be than called in a GET/HEAD request then. All just refactor the service call to use GET instead of POST.