Чем tRPC v11 отличается от v10? Какие breaking changes были введены?
tRPC v11 переработал транспортный слой: httpSubscriptionLink для SSE-подписок без WebSocket, поддержка формдата, трансформеры переехали в links. Breaking changes: новый API инициализации, изменённые типы контекста, обновлённый fetchRequestHandler.
Ключевые нововведения tRPC v11
1. httpSubscriptionLink — SSE без WebSocket
В v10 единственный способ подписок — WebSocket через wsLink. v11 добавляет httpSubscriptionLink, который использует Server-Sent Events (SSE). Это проще в деплое: не нужен отдельный WebSocket-сервер, работает через стандартный HTTP.
// v11: SSE подписки
import { createTRPCClient, httpBatchLink, httpSubscriptionLink, splitLink } from '@trpc/client';
const client = createTRPCClient<AppRouter>({
links: [
splitLink({
condition: (op) => op.type === 'subscription',
true: httpSubscriptionLink({ url: '/api/trpc' }), // SSE!
false: httpBatchLink({ url: '/api/trpc' }),
}),
],
});
2. Трансформеры переехали в links
В v10 трансформер задавался глобально при инициализации клиента. В v11 он передаётся напрямую в каждый link — это даёт гибкость: разные links могут использовать разные трансформеры.
// v10 (устарело)
const client = createTRPCProxyClient<AppRouter>({
transformer: superjson, // глобально
links: [httpBatchLink({ url: '/api/trpc' })],
});
// v11 (новый подход)
import superjson from 'superjson';
const client = createTRPCClient<AppRouter>({
links: [
httpBatchLink({
url: '/api/trpc',
transformer: superjson, // в link
}),
],
});
3. createTRPCClient вместо createTRPCProxyClient
createTRPCProxyClient переименован в createTRPCClient. Старое имя оставлено как deprecated alias, но рекомендуется обновить импорты.
// v10
import { createTRPCProxyClient } from '@trpc/client';
// v11
import { createTRPCClient } from '@trpc/client';
4. fetchRequestHandler обновлён
Адаптер для Edge Runtime и App Router стал основным вместо createNextApiHandler. API немного изменился:
// app/api/trpc/[trpc]/route.ts (v11)
import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
import { appRouter } from '../../../../server/trpc/router';
const handler = (req: Request) =>
fetchRequestHandler({
endpoint: '/api/trpc',
req,
router: appRouter,
createContext: () => ({ req }), // контекст теперь принимает Request напрямую
});
export { handler as GET, handler as POST };
5. Поддержка FormData и File Upload
v11 добавляет нативную поддержку загрузки файлов через FormData в процедурах:
// server: принимаем файл
uploadAvatar: protectedProcedure
.input(z.instanceof(FormData))
.mutation(async ({ input, ctx }) => {
const file = input.get('file') as File;
// обрабатываем файл...
return { url: '/uploads/' + file.name };
}),
6. Типы контекста и middleware
В v11 уточнены generic-типы middleware. Тип возвращаемого значения next() теперь строже типизирован — код с неявным any в middleware может начать выдавать ошибки типов при миграции.
Breaking Changes при миграции с v10
- Переместить
transformerиз корневого конфига клиента в каждый link - Заменить
createTRPCProxyClientнаcreateTRPCClient - Проверить типы middleware — могут появиться новые ошибки TypeScript
- Обновить
@trpc/server,@trpc/client,@trpc/react-queryодновременно — версии должны совпадать
Подводные камни
- Обновление только одного пакета из группы (@trpc/server без @trpc/client) приводит к ошибкам типов и рантайм-несовместимости — обновляйте все пакеты tRPC вместе.
- SSE через
httpSubscriptionLinkне работает в браузерах без поддержки EventSource — проверьте совместимость с вашей целевой аудиторией (IE11 не поддерживает). - При переносе трансформера в link нужно обновить и серверную, и клиентскую конфигурацию одновременно — промежуточное состояние приведёт к битой сериализации.
- Changelog v11 содержит экспериментальные API (помечены
unstable_) — не используйте их в продакшене, интерфейс может измениться в патч-версии. - Если проект использует кастомные links, нужно проверить совместимость observable-API — внутренние типы обновились.
- FormData upload требует настройки CSRF-защиты отдельно — tRPC не добавляет её автоматически.
- Документация v11 в период выхода была неполной — опирайтесь на changelog и issues в GitHub репозитории trpc/trpc для актуальных примеров.
Common mistakes
- Смешивать «tRPC v11 и v10» с похожим механизмом без критерия выбора.
- Игнорировать риск: неверно оценить границы применения темы «tRPC v11 и v10» и получить хрупкое решение.
- Показывать только синтаксис и не объяснять поведение в runtime или сборке.
What the interviewer is testing
- Объясняет миграция версии, обновление пакетов и изменения integration surface.
- Показывает на примере, как работает: v11 требует сверяться с migration guide, особенно для React Query integration, server adapters, links и unstable/internal imports; нельзя переносить v10 snippets без проверки текущих docs.
- Называет production-нюанс и граничный случай для темы «tRPC v11 и v10».