Without AcceptHeaderRequestCallback, I had to always specify .accept(MediaType.APPLICATION_JSON). RestTemplate was smart enough to deduce accepted content type and successfully negotiate with the server.

I hope this case is clear enough and does not need extra context, but feel free to ask why RestClient fails without explicit accepted media type

Comment From: poutsma

You are correct.

RestClient is effectively a non-reactive port of the WebClient, which also does not set the Accept header based on the response type. Both WebClient and RestClient offer direct access the request and response headers, and we felt that having an opinionated model on top of that would be confusing. That said, you can easily set up default headers in the client builder that specify the Accept header.

Comment From: michaldo

  1. As inferred header Accept is part of RestTemplate (I guess most RestTemplate users are not aware that content negotiation can be an issue - at least for me it is surprise) then documentation should be:

RestTemplate method: getForObject(String, Class, Object…​)

RestClient equivalent :

get()
.uri(String, Object…​)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.body(Class)
  1. A lot of loss was caused by botched marking RestTemplate as deprecated/maintenance mode. Trustful developers, which care their applications be ready for upgrade, replaced RestTemplate by WebClient, facing bloat code, bloat dependency, lost context without real need. Currently, documentation says RestTemplate is "high level" and RestClient is "modern". Additionally, there is a "migration" from RestTemplate to RestClient.

It is a progress comparing "deprecated", but still documentation disregards RestTemplate. As seen in 1), RestTemplate syntax is in many cases shorter, simpler and enough. I think it would be fair to document RestClient as "low level" and RestTemplate as "high level", without value

  1. RestTemplate and RestClient setup configuration has similar syntax but classes are different. If I want utilize RestTemplate for high level code and RestClient for low level code in one application, I need duplicate configuration. Moreover, MockRestServiceServer does not work well when both RestTemplate and RestClient exists - I'm going to raise a ticker for that when I found a reason.

It would be ideally to have a one way do setup "rest caller" and two ways to "call rest": low level and high level. For example, it would be useful to have method getForObject(String, Class, Object…​) in RestClient.