От переводчика

Сообщество Spring АйО представляет перевод статьи сравнения двух подходов взаимодействия с RESTful сервисами в Spring Boot: с помощью устаревшего RestTemplate, и нового RestClient. Последний предоставляет более удобный fluent интерфейс ,похожий на WebClient, появившийся в Spring Boot 3.2. Статья представляет собой достаточно поверхностное сравнение двух подходов, которое, тем не менее, дает неплохое представление о новом API.

UPD. Благодаря нашим читателям, в исходной статье были обнаружены фактические ошибки, которые были поправлены в переводе.

В мире Spring Boot отправка HTTP запросов к внешним сервисам является весьма распространенной задачей. Традиционно при достижении этой цели разработчики полагались на RestTemplate. Однако, по мере развития Spring Framework, на свет появился новый и более мощный способ обработки HTTP запросов: так называемый WebClient. Spring Boot 3.2 представил нам новый API для REST запросов: RestClient, использующий те же принципы fluent api, что и WebClient.

RestClient предлагает нам более современные и интуитивно понятные способы взаимодействия с RESTful сервисами. 

Происхождение RestTemplate

RestTemplate является одним из основных элементов экосистемы Spring на протяжении многих лет. Это синхронный клиент, предназначенный для отправки HTTP запросов и обработки ответов. Используя RestTemplate, разработчики могут легко взаимодействовать с RESTful API, используя знакомый синтаксис Java. Однако по мере того, как приложения становились более асинхронными и неблокирующими, ограничения, налагаемые RestTemplate, становились все более очевидными. 

Ниже приведен простейший пример использования RestTemplate для загрузки данных из внешнего API: 

var restTemplate = new RestTemplate(); 

var response = restTemplate.getForObject(
  "https://api.example.com/data", 
  String.class
); 

System.out.println(response);

Появление WebClient

С приходом Spring WebFlux, асинхронного, неблокирующего веб-фреймворка, на свет появляется WebClient как современная альтернатива RestTemplate. WebClient  соответствует принципам реактивности и идеально подходит для разработки реактивных приложений. Он поддерживает как синхронную, так и асинхронную коммуникацию, одновременно с этим предлагая нам fluent API для составления запросов.

Ниже приведен пример использования WebClient для выполнения того же HTTP запроса, что и в предыдущем примере:

var webClient = WebClient.create(); 

var response = webClient.get()
  .uri("https://api.example.com/data") 
  .retrieve()
  .bodyToMono(String.class); 

 response.subscribe(System.out::println);

RestClient в Spring Boot 3.2

Релиз Spring Boot 3.2 включил в себя появление RestClient, который еще больше упрощает процесс отправки HTTP запросов, предлагая более интуитивный fluent API, меньшее количество шаблонного кода.

Давайте посмотрим на пример того, как может использоваться RestClient:

var response = restClient 
  .get() 
  .uri(cepURL) 
  .retrieve() 
  .toEntity(String.class); 
 
System.out.println(response.getBody());

С RestClient код становится более лаконичным и легким к прочтению.

Сравнение RestClient с RestTemplate

Давайте сравним RestClient с RestTemplate, на примере часто встречающихся сценариев:

Инициализация объекта

RestTemplate:

var response = new RestTemplate();

RestClient:

var response = RestClient.create();

Мы также можем использовать RestTemplate для создания RestClient:

var myOldRestTemplate = new RestTemplate();             
var response = RestClient.builder(myOldRestTemplate);

GET  запрос

RestTemplate:

var response = restTemplate.getForObject(
  "https://api.example.com/data", 
  String.class
); 

RestClient:

var response = restClient 
  .get() 
  .uri(cepURL) 
  .retrieve() 
  .toEntity(String.class);

POST запрос

RestTemplate:

ResponseEntity<String> response = restTemplate.postForEntity(
  "https://api.example.com/data", 
  request, 
  String.class
); 

RestClient: 

var response = restClient 
  .post() 
  .uri("https://api.example.com/data") 
  .body(request) 
  .retrieve() 
  .toEntity(String.class);  

Обработка ошибок

RestTemplate:

try { 
  String response = restTemplate.getForObject( 
    "https://api.example.com/data",  
    String.class 
  ); 
} catch (RestClientException ex) { 
  // Handle exception 
} 

RestClient:

String request = restClient.get()  
  .uri( 
    "https://api.example.com/this-url-does-not-exist"
  )  
  .retrieve() 
  .onStatus(
    HttpStatusCode::is4xxClientError, 
    (request, response) -> {  
      throw new MyCustomRuntimeException(
        response.getStatusCode(), 
        response.getHeaders()
      )  
  }
) 
.body(String.class);

Как можно видеть из этих примеров, RestClient предлагает более лаконичный подход к отправке HTTP запросов по сравнению с RestTemplate. 

Ознакомиться с множеством других примеров использования можно в документации.

Заключение

Начиная со Spring Boot 3.2 и выше, RestClient становится современной заменой RestTemplate, предлагающей более интуитивно понятный и лаконичный способ взаимодействия с RESTful сервисами.

Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм - Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано.

Ждем всех, присоединяйтесь!