Careeroza
RestClient
Calling Another API
Your backend often calls other services: a payment gateway, an SMS provider, a courier API. Since Spring Boot 3.2 the recommended blocking client is RestClient: a fluent API on top of the same message converters you already use. (RestTemplate still works but is in maintenance mode.)
@Configuration
class HttpClientsConfig {
@Bean
RestClient courierClient(RestClient.Builder builder) { // Builder is auto-configured by Boot
return builder
.baseUrl("https://api.fastcourier.example")
.defaultHeader("X-Api-Key", "demo-key")
.build();
}
}
public record TrackingInfo(String awb, String status, String location) {}
@Service
class CourierService {
private final RestClient client;
CourierService(RestClient courierClient) { this.client = courierClient; }
TrackingInfo track(String awb) {
return client.get()
.uri("/v1/shipments/{awb}", awb)
.retrieve()
.body(TrackingInfo.class); // JSON -> record via Jackson
}
}POST with a Body and Reading the Status
public record CreateShipment(String orderId, String pincode, int weightGrams) {}
public record ShipmentCreated(String awb, String eta) {}
ResponseEntity<ShipmentCreated> response = client.post()
.uri("/v1/shipments")
.contentType(MediaType.APPLICATION_JSON)
.body(new CreateShipment("SE-1001", "560001", 350))
.retrieve()
.toEntity(ShipmentCreated.class);
System.out.println(response.getStatusCode() + " " + response.getBody());Console output:
201 CREATED ShipmentCreated[awb=FC77812093IN, eta=2026-10-15]
Tip: For lists use .body(new ParameterizedTypeReference<List<TrackingInfo>>() {}).
HTTP Interfaces
Spring 6 can generate a client from an annotated interface, much like Feign:
public interface CourierApi {
@GetExchange("/v1/shipments/{awb}")
TrackingInfo track(@PathVariable String awb);
@PostExchange("/v1/shipments")
ShipmentCreated create(@RequestBody CreateShipment request);
}
@Bean
CourierApi courierApi(RestClient courierClient) {
HttpServiceProxyFactory factory = HttpServiceProxyFactory
.builderFor(RestClientAdapter.create(courierClient)).build();
return factory.createClient(CourierApi.class);
}