Розробка tRPC API для веб-застосунку

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

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

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка tRPC API для веб-застосунку
Середня
~3-5 робочих днів
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розробка tRPC API для веб-додатку

tRPC (TypeScript RPC)—бібліотека для побудови end-to-end типізованих API без схем та кодогенерації. TypeScript типи автоматично передаються від серверних процедур до клієнтських викликів. Працює тільки в екосистемі TypeScript й найзручніше в monorepo або fullstack-фреймворках (Next.js, Remix, SvelteKit).

Ключова ідея

// Сервер визначає процедуру
const appRouter = router({
  getUser: publicProcedure
    .input(z.object({ id: z.string() }))
    .query(async ({ input, ctx }) => {
      return ctx.db.user.findUnique({ where: { id: input.id } });
    }),
});

// Клієнт викликає з повною типізацією—без кодогенерації
const user = await trpc.getUser.query({ id: 'user_123' });
// TypeScript знає тип user: { id: string; name: string; ... } | null

Нема REST-ендпоїнтів, нема OpenAPI схем, нема GraphQL—просто функції з типами.

Налаштування (Next.js + tRPC v11)

// server/trpc.ts
import { initTRPC, TRPCError } from '@trpc/server';
import { ZodError } from 'zod';

const t = initTRPC.context<Context>().create({
  errorFormatter({ shape, error }) {
    return {
      ...shape,
      data: {
        ...shape.data,
        zodError: error.cause instanceof ZodError ? error.cause.flatten() : null,
      },
    };
  },
});

export const router = t.router;
export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(({ ctx, next }) => {
  if (!ctx.session?.user) throw new TRPCError({ code: 'UNAUTHORIZED' });
  return next({ ctx: { ...ctx, user: ctx.session.user } });
});

Маршрутизатор та процедури

// server/routers/articles.ts
export const articlesRouter = router({
  list: publicProcedure
    .input(z.object({ page: z.number().default(1), limit: z.number().max(100).default(20) }))
    .query(async ({ input, ctx }) => {
      const [items, total] = await ctx.db.$transaction([
        ctx.db.article.findMany({ skip: (input.page - 1) * input.limit, take: input.limit }),
        ctx.db.article.count(),
      ]);
      return { items, total, pages: Math.ceil(total / input.limit) };
    }),

  create: protectedProcedure
    .input(z.object({ title: z.string().min(1).max(200), body: z.string().min(10) }))
    .mutation(async ({ input, ctx }) =>
      ctx.db.article.create({ data: { ...input, authorId: ctx.user.id } })
    ),

  delete: protectedProcedure
    .input(z.string())
    .mutation(async ({ input: id, ctx }) => {
      const article = await ctx.db.article.findUnique({ where: { id } });
      if (!article) throw new TRPCError({ code: 'NOT_FOUND' });
      if (article.authorId !== ctx.user.id) throw new TRPCError({ code: 'FORBIDDEN' });
      return ctx.db.article.delete({ where: { id } });
    }),
});

Клієнт з React Query

// Автотипізація, кешування через React Query
function ArticleList() {
  const { data, isLoading } = trpc.articles.list.useQuery({ page: 1 });
  const createMutation = trpc.articles.create.useMutation({
    onSuccess: () => utils.articles.list.invalidate(),
  });

  if (isLoading) return <Spinner />;

  return (
    <div>
      {data?.items.map(article => <ArticleCard key={article.id} {...article} />)}
      <button onClick={() => createMutation.mutate({ title: '...', body: '...' })}>
        {createMutation.isPending ? 'Створюється...' : 'Створити'}
      </button>
    </div>
  );
}

Коли використовувати tRPC

Ідеально для: fullstack TypeScript monorepo, мінімального API overhead, внутрішніх microservice API, швидкої ітерації зі спільними типами.

Не підходить для: публічних API з non-TS клієнтами, потреби у строгих REST/GraphQL контрактах, команд без TypeScript експертизи.

Терміни

Базова tRPC настройка (router, процедури, client hooks): 1–2 дні. З аутентифікацією, інтеграцією БД, складною валідацією вхідних даних: 3–5 днів.