Розробник витратив два тижні на заміну REST API на tRPC у внутрішньому інструменті.

Чому ця зміна була важливою

Старий стек змушував нас підтримувати DTO, валідатор і окремий набір типів TypeScript для фронтенду. Перейменуйте поле на бекенді — і API все одно повертало 200, UI продовжував рендеритись, а помилка проявлялася лише у вигляді значень «undefined». Клієнт помітив проблему раніше, ніж хтось із команди. REST-контракти приховували проблему, а зайві файли створювали навантаження на підтримку, яке ніколи не окупалося.

Як виглядав REST-сетап

  • OpenAPI spec — статичний файл, який описував ендпоінти, але ніколи не був єдиним джерелом істини.
  • Крок генерації Client SDK — CI-завдання, яке створювало JavaScript-обгортку.
  • Колекція Postman — спільний артефакт для тестування, яким ніхто не користувався.
  • Ручні TypeScript інтерфейси — написані вручну типи, які мали синхронізуватися з сервером.

Кожна зміна API торкалася принаймні трьох із цих артефактів, плюс валідатора та будь-яких наступних викликів fetch. Процес був повільним і схильним до помилок.

Як tRPC скоротив кодову базу

tRPC усуває потребу в окремому файлі контрактів. Сервер експортує тип роутера; клієнт імпортує той самий тип. Перейменуйте поле на бекенді — і редактор миттєво підсвітить невідповідність без запуску коду чи невдалих запитів. Розробник видалив:

  • Файл OpenAPI spec.
  • Крок генерації client SDK.
  • Невикористовувану колекцію Postman.
  • Папку з ручними TypeScript інтерфейсами.

Репозиторій став легшим, а фідбек почав надходити під час розробки, а не після розгортання.

Обмеження tRPC

tRPC працює лише тоді, коли обидва кінці використовують TypeScript. Він не підходить, якщо:

  • Мобільна команда використовує Swift або Kotlin.
  • API мають використовувати зовнішні партнери.
  • Вам потрібен публічний, незалежний від мови інтерфейс.

Що насправді знадобилося для міграції

Двотижнева робота була чимось більшим, ніж просто копіюванням і вставкою. Розробнику довелося:

  • Переписати кожен виклик fetch, щоб використовувати клієнтські функції tRPC.
  • Налаштувати логіку обробки помилок.
  • Оновити UI-компоненти, які залежали від станів завантаження (loading) та повторних спроб (retry), прив'язаних до сирих HTTP-відповідей.

Питання, які варто поставити перед переходом

  • Чи використовують фронтенд і бекенд TypeScript? Без спільної системи типів tRPC втрачає свою головну перевагу.
  • Чи одна й та сама команда відповідає за обидві сторони? Розриви в зоні відповідальності можуть знову призвести до розсинхронізації контрактів.
  • Ви виправляєте конкретну помилку чи просто слідуєте тренду? Приріст продуктивності реальний, але він має вирішувати існуючу проблему.

Гібридний підхід для 2025 року

Багато команд знаходять золоту середину, використовуючи обидва стеки:

  • tRPC для внутрішніх рівнів застосунку, де кодова база повністю на TypeScript, а одна й та сама команда володіє і сервером, і клієнтом.
  • REST для вебхуків, публічних API та інтеграцій із партнерами, де потрібен доступ, незалежний від мови програмування.

Використання правильного інструмента для кожного рівня дозволяє підтримувати швидкість внутрішньої розробки, зберігаючи при цьому відкритість, необхідну для зовнішніх споживачів.

Висновок: Заміна REST на tRPC може усунути дублювання артефактів контрактів і виявляти помилки ще на етапі редагування коду, але переваги з'являться лише тоді, коли весь стек використовує TypeScript, а команда готова взяти на себе витрати на міграцію. Змішана стратегія дозволяє отримати переваги, не обмежуючи споживачів, які не використовують TypeScript.