Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+717новых вакансий за сутки·60 871вакансия открыта сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании5 951
РезюмеAIПодготовкаСтатьи
ТарифыТарифы
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 391 кандидат открыт к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python9 224
  • Облачные технологии4 076
  • QA вакансии1 588
  • Android1 322
  • Инженер данных805
  • Продакт-менеджер368

Разработка

  • Backend вакансии1 317
  • iOS1 239
  • AI вакансии608
  • Fullstack вакансии523
  • Frontend вакансии456
  • Mobile вакансии28

По стеку

  • Go5 445
  • Java3 175
  • Kotlin1 119
  • Node.js1 026
  • Rust949
  • .NET666
  • PHP311
  • C#210
  • C++204

DevOps и инфраструктура

  • DevOps вакансии2 713
  • Kubernetes2 308
  • Linux-инфраструктура1 890
  • Terraform / IaC1 406
  • CI/CD842
  • Мониторинг и Observability645
  • SRE226
  • Кибербезопасность84

Аналитика и данные

  • Аналитик данных483
  • Data Scientist469
  • Бизнес-аналитик349
  • Системный аналитик48

Другие направления

  • Проджект-менеджер139
  • UI/UX дизайн71
  • Ручное тестирование14

По регионам

  • Вакансии в США24 791
  • Вакансии в Европе9 439
  • Работа в России2 924
  • Вакансии в Канаде2 178

По формату

  • Удалённые вакансии43 505
  • Релокация в США24 791
  • Гибридная работа3 370
  • Офисная работа2 525

По уровню

  • Senior вакансии20 898
  • Middle вакансии12 438
  • Junior вакансии3 864

Сейчас нанимают

Все компании
  • Wise191 вакансия
  • Rakuten188 вакансий
  • ASML163 вакансии
  • Grab134 вакансии
  • Celonis48 вакансий
  • Spotify37 вакансий
  • Adyen28 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace17 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме tRPCВсе вопросы
tRPCMiddleТеория

Как объединить несколько tRPC-роутеров в один корневой роутер?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

Несколько роутеров объединяются через t.router({ users: userRouter, posts: postRouter }). В tRPC v11 также доступен t.mergeRouters() для плоского слияния без вложенности.

Способ 1: вложенные роутеры (рекомендуется)

// server/routers/user.ts
import { router, protectedProcedure } from '../trpc';
import { z } from 'zod';

export const userRouter = router({
  getMe: protectedProcedure.query(({ ctx }) => ctx.user),
  update: protectedProcedure
    .input(z.object({ name: z.string().min(1) }))
    .mutation(({ input, ctx }) => {
      return db.user.update({
        where: { id: ctx.user.id },
        data: { name: input.name },
      });
    }),
});
// server/routers/post.ts
import { router, publicProcedure, protectedProcedure } from '../trpc';
import { z } from 'zod';

export const postRouter = router({
  list: publicProcedure.query(() => db.post.findMany()),
  create: protectedProcedure
    .input(z.object({ title: z.string(), body: z.string() }))
    .mutation(({ input, ctx }) => {
      return db.post.create({
        data: { ...input, authorId: ctx.user.id },
      });
    }),
});
// server/routers/_app.ts
import { router } from '../trpc';
import { userRouter } from './user';
import { postRouter } from './post';
import { authRouter } from './auth';

export const appRouter = router({
  user: userRouter,   // → trpc.user.getMe()
  post: postRouter,   // → trpc.post.list()
  auth: authRouter,   // → trpc.auth.login()
});

export type AppRouter = typeof appRouter;

Объединение роутеров в tRPC

В реальных приложениях API разбивается на доменные роутеры (users, posts, auth и т.д.), которые потом объединяются в один корневой appRouter. tRPC поддерживает два способа объединения.

Способ 2: t.mergeRouters() — плоское слияние (v11)

Если нужны процедуры на верхнем уровне без вложенности:

// server/routers/_app.ts
import { t } from '../trpc';
import { userRouter } from './user';
import { postRouter } from './post';

// Процедуры объединяются в одно пространство имён
export const appRouter = t.mergeRouters(userRouter, postRouter);
// Результат: trpc.getMe(), trpc.list() — без префиксов

export type AppRouter = typeof appRouter;

Экспорт типа AppRouter

Критически важно экспортировать только тип, а не сам роутер, на клиент:

// Правильно — только тип, без runtime-импорта серверного кода
export type { AppRouter } from '@/server/routers/_app';

// Неправильно — утащит весь серверный код в клиентский бандл
import { appRouter } from '@/server/routers/_app';

Подключение к HTTP-хендлеру

// app/api/trpc/[trpc]/route.ts (Next.js App Router)
import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
import { appRouter } from '@/server/routers/_app';
import { createContext } from '@/server/context';

const handler = (req: Request) =>
  fetchRequestHandler({
    endpoint: '/api/trpc',
    req,
    router: appRouter,
    createContext,
  });

export { handler as GET, handler as POST };

Подводные камни

  • Конфликты имён в mergeRouters: если два роутера имеют одноимённые процедуры, один перезапишет другой без предупреждения TypeScript.
  • Circular imports: если роутеры импортируют друг друга, возникнет циклическая зависимость — разбивайте на слои (db → services → routers).
  • AppRouter тип нельзя импортировать на клиент как значение: только import type, иначе серверный код попадёт в браузер.
  • Глубокая вложенность усложняет рефакторинг: больше двух уровней вложенности (trpc.admin.user.ban()) сложно поддерживать.
  • Нельзя смешивать роутеры из разных initTRPC: типы будут несовместимы.
  • mergeRouters в v11 заменяет устаревший router.merge(): не используйте старый API.
  • Горячая перезагрузка в Next.js dev: при изменении роутера может потребоваться перезапуск из-за кэша модулей.

Частые вопросы на собеседовании

  • Чем tRPC отличается от REST и GraphQL? Когда стоит выбрать tRPC вместо них?
  • Как реализовать защищённые процедуры (protected procedures) с помощью middleware и context?
  • Как добавить валидацию входных данных к процедурам tRPC с помощью Zod?
  • В каких типах frontend-проектов tRPC даёт реальный выигрыш, а где будет избыточен или неудачен?

Типичные ошибки

  • Смешивать «объединение tRPC routers» с похожим механизмом без критерия выбора.
  • Игнорировать риск: неверно оценить границы применения темы «объединение tRPC routers» и получить хрупкое решение.
  • Показывать только синтаксис и не объяснять поведение в runtime или сборке.

Что проверяет интервьюер

  • Объясняет композиция доменных router'ов в корневой API.
  • Показывает на примере, как работает: root router собирает feature routers в дерево namespaces, а merge или nested routers должны сохранять типы без циклических зависимостей между пакетами.
  • Называет production-нюанс и граничный случай для темы «объединение tRPC routers».

Как вы знаете этот вопрос?

Проверить себя по теме tRPC →

Источники

  • https://trpc.io/docs/server/merging-routers
  • https://trpc.io/docs/server/routers
←Предыдущий вопросКак тестировать процедуры tRPC? Какие подходы рекомендуются?

Связанные темы

tRPCapi-designbackend-architecture