От переводчика
Сообщество 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 и всего, что с ним связано.
Ждем всех, присоединяйтесь!
Комментарии (7)
breninsul
18.06.2024 12:57+3Будучи надстройкой над WebClient, RestClient также удовлетворяет требованиям реактивности, при этом упрощая процесс отправки HTTP запросов.
И про "надстройку над WebClient" много где сказано
Идем в спринг, там
Spring Framework 6.1 M2 introduces the RestClient, a new synchronous HTTP client
RestClient offers the fluent API of WebClient with the infrastructure of RestTemplate.
В общем что-то вы напутали, он синхронный, а с WebClient роднит только стилистика API
spring_aio Автор
18.06.2024 12:57+2Да, вы правы, ошибка в оригинальной статье. Там мы ее исправить не можем, поэтому поправили только перевод)
arkaev
Речь точно про лаконичность нового интерфейса? Примеры говорят об обратном: многословнее и обработка ошибок менее интуитивна. Вся затея как раз в реактивном подходе, но он тоже не для всех задач и ситуаций нужен.
Вот если нужен асинхронный ответ в виде Feature, например, то это один из возможных вариантов
alexander-shustanov
На мой взгляд, API более удобный
Можно сравнение по ссылке посмотреть https://docs.spring.io/spring-framework/reference/integration/rest-clients.html#_migrating_from_resttemplate_to_restclient
множество похожих методов заменены понятными билдерами
alexander-shustanov
fluent interface если быть точным