You have do this:
RestClient rest = RestClient
.builder(builder.setConnectTimeout(Duration.ofSeconds(30))
.setReadTimeout(Duration.ofSeconds(30))
.rootUri("https://example.com)
.build())
.defaultHeader("Authorization", "Bearer " + properties.token())
.baseUrl("https://example.com")
.build();
If you only configure rootUri on the RestTemplateBuilder, it's ignored by RestClient.Builder as the built RestTemplate has a UriTemplateHandler that isn't a UriBuilderFactory. If you only configure baseUrl on the RestClient.Builder it's ignored as the UriBuilderFactory from the RestTemplate is used instead. Configuring both prevents the UriBuilderFactory from the RestTemplate from being used which then allows the baseUrl on the RestClient.Builder to be honored.
Comment From: scottfrederick
If you only configure
rootUrion theRestTemplateBuilder, it's ignored byRestClient.Builderas the builtRestTemplatehas aUriTemplateHandlerthat isn't aUriBuilderFactory.
This can be fixed by making the RootUriTemplateHandler used by RestTemplateBuilder extend Framework's DefaultUriBuilderFactory.
If you only configure
baseUrlon theRestClient.Builderit's ignored as theUriBuilderFactoryfrom theRestTemplateis used instead.
This was a problem in Framework that has been fixed by https://github.com/spring-projects/spring-framework/issues/32180.
Configuring both prevents the
UriBuilderFactoryfrom theRestTemplatefrom being used which then allows thebaseUrlon theRestClient.Builderto be honored.
After the fix for the first scenario, the UriBuilderFactory from the RestTemplate will be used instead of the RestClient.Builder.baseUrl() value. This decision is made in Framework code, and is out of Spring Boot's control. You'll get the same behavior if you create a RestTemplate and call setUriTemplateHandler on it without using Boot's RestTemplateBuilder.
I have a test that verifies all three scenarios, but the second test case won't pass until we move to Spring Framework 6.1.4 snapshots. I'll wait until then to push the changes.