РАЗРАБОТКА

Ky 2.0 обновил хуки и таймауты и снова бросил вызов axios

Ky 2.0 вышел 18 июня с новыми хуками, totalTimeout и валидацией схем. Для JavaScript-разработчиков это более зрелая fetch-native альтернатива axios.

✍️ Редакция iTech News | 19.06.2026 | ⏱ 6 мин | Источник: InfoQ
💻

Ky 2.0 вышел 18 июня и привез не косметику, а довольно взрослый пересмотр API: новые хуки, переработанные таймауты, более понятную работу с URL и встроенную валидацию ответов по схемам. Для русскоязычной аудитории, которая давно живет между нативным fetch и тяжеловатыми обвязками вроде axios, это сигнал простой: у легковесного HTTP-клиента появился набор функций, ради которых раньше обычно писали собственный слой поверх Fetch API.

О релизе Ky 2.0 сообщает InfoQ. Речь идет об open source-клиенте для JavaScript, который изначально строился вокруг Fetch API и позиционируется как компактная альтернатива axios. Проект поддерживают Синдре Сорхус, Сет Холладей и Шимон Марчак, а сам релиз авторы называют первым большим мажорным обновлением за несколько лет. Изменения здесь не для галочки: они затрагивают способ расширения клиента, обработку ошибок, ретраи и типизацию ответов.

Главная инженерная правка касается хуков. В версии 2.0 beforeRequest, afterResponse, beforeRetry и beforeError получили единый формат аргумента: теперь они принимают один объект состояния вида {request, options, retryCount, ...} вместо набора разрозненных параметров. На бумаге это выглядит как скучная чистка API, но на практике именно такие вещи убирают мелкую боль из кода библиотек и внутренних SDK. Плюс появился новый хук init, который срабатывает раньше остальных, а beforeError теперь вызывается для всех типов ошибок, а не только для HTTPError. Для тех, кто строит поверх клиента свои плагины, логирование, retry-политику или централизованную трассировку, это уже не «удобнее», а просто предсказуемее.

Второй заметный блок изменений связан с таймаутами. Раньше у Ky был таймаут на отдельную попытку запроса. Теперь к нему добавили totalTimeout, который ограничивает всю операцию целиком, включая повторные попытки и задержки между ними. Если лимит исчерпан, библиотека выбрасывает TimeoutError. Это маленькая, но очень практичная деталь: в продакшене бизнес-логике обычно все равно, где именно завис вызов, на первой попытке или на третьей. Ее интересует общий бюджет времени. Такой механизм особенно полезен для BFF-сервисов, edge-функций и любых API-агрегаторов, где одна медленная зависимость может протянуть за собой весь ответ наружу.

Отдельно авторы подтянули логику повторных запросов. В релизе появился отдельный класс NetworkError, а автоматические ретраи теперь зарезервированы для реальных сетевых сбоев вроде DNS-ошибок или отказа соединения, а не для программных багов. Это важное разделение. В экосистеме JavaScript слишком много кода, где retry включен «на всякий случай», а потом поломанный обработчик, неверная сериализация или ошибка в конфигурации начинают повторяться с удвоенным энтузиазмом. Здесь команда Ky явно пытается провести жесткую границу между нестабильной сетью и сломанной логикой приложения.

Что меняется для команд, которые живут на fetch

Еще один старый источник путаницы в подобных клиентах — работа с базовыми URL. В Ky 2.0 опцию prefixUrl переименовали в prefix и разрешили использовать ведущие слэши во входных путях. Параллельно появилась новая опция baseUrl, которая следует стандартной логике разрешения URL. На первый взгляд это мелочь из серии «назвали по-другому», но любой разработчик, который хотя бы раз пытался подружить кастомный инстанс HTTP-клиента, префиксы роутов и query-параметры из нескольких слоев конфигурации, знает цену таким мелочам. Тем более что searchParams теперь сливаются с уже существующими параметрами в URL, а не ведут себя как отдельный мир со своими законами.

Не менее интересна встроенная валидация ответов в .json(). Ky добавил поддержку Standard Schema и умеет проверять данные через библиотеки вроде Zod и Valibot. Для TypeScript-разработчиков это, пожалуй, один из самых сильных аргументов в пользу клиента: валидация и вывод типов оказываются ближе к точке получения данных, а не размазаны по сервисам и адаптерам. На фоне растущей популярности schema-first-подхода это выглядит не как приятный бонус, а как попытка сделать типобезопасный HTTP-клиент нормой по умолчанию. Плюс HTTPError теперь отдает заранее распарсенное поле data, так что тело ошибки можно читать без повторного вызова error.response.json(). Заодно, как пишет InfoQ, это закрывает проблему с утечками ресурсов.

Судя по реакции ранних пользователей, рынок как минимум заметил релиз. В обсуждении на Hacker News мейнтейнер Сет Холладей назвал предрелизную работу пакетом «улучшений качества жизни» и отдельно подчеркнул, что были исправлены все известные баги и закрыты странности вокруг базовых URL для кастомных инстансов. На вопрос о сравнении с axios он ответил еще прямее: Ky изначально писали под fetch, тогда как axios пытается приспособиться к fetch-модели задним числом, и это не всегда работает хорошо. В Reddit реакция была еще проще и ближе к боевой реальности: один из разработчиков описал библиотеку как «fetch++», другой заметил, что это ровно тот слой обвязки, который обычно приходится писать самому, а потом еще и тестировать без всякого желания.

Почему это важно именно сейчас

Контекст у релиза удачный. За последние годы фронтенд и серверный JavaScript все сильнее сдвинулись в сторону нативного fetch: он уже не выглядит экспериментом, одинаково живет в браузерах, Node.js, Bun и Deno, а разработчики все реже хотят тащить тяжелый HTTP-клиент только ради пары удобных абстракций. Но у «голого» fetch по-прежнему есть свои шероховатости: таймауты, повторные попытки, единая обработка ошибок, нормальная типизация, валидация ответа, композиция URL. Именно на этом поле и играет Ky. То есть речь не о борьбе с axios в лоб по всем пунктам, а о том, что для части новых проектов вопрос «зачем нам axios?» теперь придется отвечать куда предметнее.

Впрочем, релиз не из серии «обновились и забыли». У мажорной версии есть вполне конкретная цена миграции. Ky 2.0 требует Node.js 22. Колбэки хуков нужно перевести на новый формат с единым объектом состояния. Метод .json() на пустых ответах и статусе 204 теперь выбрасывает исключение вместо возврата пустой строки. Тела ошибок надо читать из error.data, а не через error.response.json(). Для старых кодовых баз, особенно если библиотека завернута в собственные абстракции, это означает аудит контрактов и тестов, а не просто замену номера версии в package.json. Хорошая новость в том, что авторы приложили полноценный migration guide с примерами «до» и «после», так что это скорее инженерная рутина, чем археология.

В более широком смысле Ky 2.0 показывает, куда вообще движется слой работы с HTTP в JavaScript: меньше универсальных комбайнов, больше fetch-native инструментов, которые закрывают ровно те 20% проблем, из-за которых команды обычно и пишут собственную обвязку. Открытый вопрос теперь не в том, сможет ли Ky забрать часть аудитории у axios, а в том, сколько команд готовы обменять привычку на более строгую, типизированную и предсказуемую модель сетевого клиента.

Поделиться: Telegram X LinkedIn