Больше десяти лет
Прямолинейный. Синхронный. Простой.
С выходом Spring Framework 6 и Spring Boot 3 пришла современная замена:
- RestClient
❓ Чем обычно характеризуется
- API на методах (getForObject, postForEntity и т.д.)
- Очень явные вызовы под каждую HTTP-операцию
- Мало “цепочек”: часто один вызов укладывается в одну строку
- Настройки раскиданы по разным местам (interceptors, error handlers, converters)
- Синтаксис исторически нарастал кусками годами
Типичный пример:
Работает, но когда запрос усложняется (headers, auth, ошибки, таймауты), читаемость начинает страдать.
❓ RestClient меняет подход к API
- Флюентный, декларативный синтаксис
- Четкое разделение между сборкой request и чтением response
- Лучше читается, когда есть headers, params, auth и т.п.
- Единый, консистентный API для всех HTTP-методов
- Централизованный builder для общей конфигурации
Типичный пример:
Это та же идея, что у RestTemplate, но API яснее, расширяемее и проще поддерживать.
❓ Зачем RestClient, если уже есть WebClient
WebClient реактивный и неблокирующий (под другую задачу)
RestClient работает как RestTemplate: обычный (не реактивный) и с ожиданием ответа, просто это его современная замена.
Многим нужен современный API, но без перехода на реактивный стек.
Spring не пытается всех загнать в WebFlux. Он просто обновил классический HTTP-клиент.
Нет, он не умер, просто его только поддерживают: багфиксы и совместимость, без новых фич.
То есть новых возможностей не будет. Только апдейты совместимости.
А развитие будет происходить в RestClient.
Причем RestClient можно создать на базе RestTemplate:
❓ Что использовать сегодня:
Используй RestTemplate, если:
- приложение легаси
- миграция слишком дорогая
- завязан на библиотеки, которые работают только с RestTemplate
Используй RestClient, если:
- ты на Boot 3 / Spring 6+
- хочешь современный и чистый API
- хочешь остаться в императивном стиле
- не хочешь или не можешь использовать WebFlux
RestTemplate это классика, почти любой Java-разработчик на Spring хотя бы раз с ним сталкивался.
Но RestClient задает точку старта для нового.
Это не про реактивность и не про переделку архитектуры.
Это просто современный HTTP-клиент, который делает код понятнее и проще в сопровождении.
Похоже на подход многих других модулей Spring, где builder упрощает создание объектов и использование классов.
И в мире, где сервисы постоянно дергают внешние API, хороший HTTP-клиент реально важен.
👉 Java Portal
RestTemplate был главным вариантом для HTTP-запросов в Spring.Прямолинейный. Синхронный. Простой.
Он больше не развивается: новых фич и улучшений не будет, плюс есть ограничения по ошибкам и расширяемости.
С выходом Spring Framework 6 и Spring Boot 3 пришла современная замена:
RestTemplate- API на методах (getForObject, postForEntity и т.д.)
- Очень явные вызовы под каждую HTTP-операцию
- Мало “цепочек”: часто один вызов укладывается в одну строку
- Настройки раскиданы по разным местам (interceptors, error handlers, converters)
- Синтаксис исторически нарастал кусками годами
Типичный пример:
RestTemplate rest = new RestTemplate();
ResponseEntity<User> response =
rest.exchange(url, HttpMethod.GET, request, User.class);
Работает, но когда запрос усложняется (headers, auth, ошибки, таймауты), читаемость начинает страдать.
- Флюентный, декларативный синтаксис
- Четкое разделение между сборкой request и чтением response
- Лучше читается, когда есть headers, params, auth и т.п.
- Единый, консистентный API для всех HTTP-методов
- Централизованный builder для общей конфигурации
Типичный пример:
User user = client.get()
.uri(url)
.header("Authorization", token)
.retrieve()
.body(User.class);
Это та же идея, что у RestTemplate, но API яснее, расширяемее и проще поддерживать.
WebClient реактивный и неблокирующий (под другую задачу)
RestClient работает как RestTemplate: обычный (не реактивный) и с ожиданием ответа, просто это его современная замена.
Многим нужен современный API, но без перехода на реактивный стек.
Spring не пытается всех загнать в WebFlux. Он просто обновил классический HTTP-клиент.
❓ RestTemplate “мертв”
Нет, он не умер, просто его только поддерживают: багфиксы и совместимость, без новых фич.
То есть новых возможностей не будет. Только апдейты совместимости.
А развитие будет происходить в RestClient.
Причем RestClient можно создать на базе RestTemplate:
RestTemplate oldRestTemplate;
var restClient = RestClient.create(oldRestTemplate);
Используй RestTemplate, если:
- приложение легаси
- миграция слишком дорогая
- завязан на библиотеки, которые работают только с RestTemplate
Используй RestClient, если:
- ты на Boot 3 / Spring 6+
- хочешь современный и чистый API
- хочешь остаться в императивном стиле
- не хочешь или не можешь использовать WebFlux
RestTemplate это классика, почти любой Java-разработчик на Spring хотя бы раз с ним сталкивался.
Но RestClient задает точку старта для нового.
Это не про реактивность и не про переделку архитектуры.
Это просто современный HTTP-клиент, который делает код понятнее и проще в сопровождении.
Похоже на подход многих других модулей Spring, где builder упрощает создание объектов и использование классов.
И в мире, где сервисы постоянно дергают внешние API, хороший HTTP-клиент реально важен.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍6😁1
Java tip : можно использовать List.of() и Set.of(), чтобы создавать неизменяемые (immutable) коллекции.
Это быстрый способ получить немодифицируемые списки и множества без Collections.unmodifiableList().
Пример:
❌
👉 Java Portal
Это быстрый способ получить немодифицируемые списки и множества без Collections.unmodifiableList().
Пример:
List<String> letters = List.of("A", "B", "C");letters.add("D"); // исключение во время выполненияPlease open Telegram to view this post
VIEW IN TELEGRAM
🤯7👍6👀3
Представь, что тебя связали, кинули в багажник и увезли в ангар за городом
Похититель наклоняется к твоему уху и шепчет: "Или ты правильно отвечаешь на 3 вопроса, или пуля летит тебе прямиком в висок:
💚 Почему @Transactional в Spring не работает, если вызвать метод внутри того же класса?
💚 Почему Kafka с exactly-once семантикой в 3 раза медленнее обычной и когда можно на это забить?
💚 2 запроса одновременно читают баланс 1000₽, вычитают по 600₽ и сохраняют - что окажется в бд?
"
Ну как? Выживешь в такой ситуации?
А ведь именно так сейчас выглядит рынок найма - эти вопросы взяты с реальных собесов😯
Рынок усложнился, и на вакансию джуна спрашивают как на синьора 3 года назад. Нужно реально шарить, и шарить глубоко, только на одних нейронках далеко не уедешь
Чтобы разобраться раз и навсегда со Spring, Kafka, Redis Паша Сорокин 18 декабря в 19:00 по МСК проведёт живой открытый урок для Java-разработчиков и тех, кто хочет им стать:
💚 За какие темы надо шарить, чтобы получить оффер на миддла
💚 В каком порядке и до какой глубины их изучать
💚 По каждой технологии (Spring Boot, HTTP, REST, Postgresql, Hibernate, микросервисы, Kafka, Redis) разберут как делать не надо и как делать надо
🟢 Ссылка на урок будет в закрытом канале урока
В этом же канале вас ждёт подарок - гайд "Roadmap из 11 шагов до ЗП в 200.000+"
P.S. Паша - ex Senior Dev в ВТБ с 6 годами коммерческого опыта, так что фигни не посоветует))
Похититель наклоняется к твоему уху и шепчет: "Или ты правильно отвечаешь на 3 вопроса, или пуля летит тебе прямиком в висок:
"
Ну как? Выживешь в такой ситуации?
А ведь именно так сейчас выглядит рынок найма - эти вопросы взяты с реальных собесов
Рынок усложнился, и на вакансию джуна спрашивают как на синьора 3 года назад. Нужно реально шарить, и шарить глубоко, только на одних нейронках далеко не уедешь
Чтобы разобраться раз и навсегда со Spring, Kafka, Redis Паша Сорокин 18 декабря в 19:00 по МСК проведёт живой открытый урок для Java-разработчиков и тех, кто хочет им стать:
В этом же канале вас ждёт подарок - гайд "Roadmap из 11 шагов до ЗП в 200.000+"
P.S. Паша - ex Senior Dev в ВТБ с 6 годами коммерческого опыта, так что фигни не посоветует))
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🤔2👍1🤯1
Postgres 18 получил поддержку виртуальных вычисляемых колонок. Вычисляемые STORED-колонки в Postgres уже были несколько версий подряд.
Вычисляемые колонки позволяют:
• создавать колонку на основе других данных
• ссылаться на значения из других колонок
• заранее считать колляции или любые вычисления в базе, а не в приложении
Синтаксис GENERATED ALWAYS AS открывает выражение, а в конце указывается режим VIRTUAL или STORED.
Виртуальные вычисляемые колонки пересчитываются при каждом чтении, поэтому не подходят для тяжёлых вычислений. Для таких случаев лучше использовать STORED-колонку или даже expression index. Но они удобны, когда значение нужно редко и его логично вычислять на лету.
Пример:
👉 Java Portal
Вычисляемые колонки позволяют:
• создавать колонку на основе других данных
• ссылаться на значения из других колонок
• заранее считать колляции или любые вычисления в базе, а не в приложении
Синтаксис GENERATED ALWAYS AS открывает выражение, а в конце указывается режим VIRTUAL или STORED.
Виртуальные вычисляемые колонки пересчитываются при каждом чтении, поэтому не подходят для тяжёлых вычислений. Для таких случаев лучше использовать STORED-колонку или даже expression index. Но они удобны, когда значение нужно редко и его логично вычислять на лету.
Пример:
CREATE TABLE products (
id serial PRIMARY KEY,
price numeric,
tax_rate numeric DEFAULT 0.05,
total_price numeric GENERATED ALWAYS AS (price * (1 + tax_rate)) VIRTUAL
);
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Совет по Java: используйте default-методы в интерфейсах для поддержки обратной совместимости (начиная с Java 8).
Допустим, у вас есть интерфейс Shape:
Типичная реализация выглядит так:
Теперь нужно добавить метод perimeter(). Если добавить обычный метод в интерфейс, все существующие реализации Shape сломаются. Вместо этого можно добавить default-метод.
Класс Circle автоматически получает реализацию default-метода. При необходимости его можно переопределить.
пример : https://gist.github.com/mcasari/b0ee1d94046793ba20f02538ef916f48
👉 Java Portal
Допустим, у вас есть интерфейс Shape:
interface Shape {
double area();
}Типичная реализация выглядит так:
class Circle implements Shape {
private double radius;
Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}Теперь нужно добавить метод perimeter(). Если добавить обычный метод в интерфейс, все существующие реализации Shape сломаются. Вместо этого можно добавить default-метод.
interface Shape {
double area();
// Новый метод
default double perimeter() {
...
}
}Класс Circle автоматически получает реализацию default-метода. При необходимости его можно переопределить.
пример : https://gist.github.com/mcasari/b0ee1d94046793ba20f02538ef916f48
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤4