oRPC Когда типы спасают мир API

16 Feb, 2026

oRPC logo

Когда разработка API превращается в квест

Знакома ли вам ситуация, когда фронтенд-разработчик ждет, пока бэкенд закончит эндпоинт, чтобы начать свою часть работы? Или когда API уже готов, но документация устарела, и приходится гадать, какие поля принимать, а какие отдавать? А постоянные ошибки из-за несовпадения типов данных между клиентом и сервером? Это не просто раздражает, это замедляет разработку, увеличивает количество багов и, в конечном итоге, бьет по нервам всей команды.

Мы, разработчики, постоянно ищем способы сделать нашу жизнь проще, а код — надежнее. И вот тут на сцену выходит проект, который обещает решить многие из этих головных болей, объединяя лучшее из двух миров: RPC и OpenAPI. Встречайте — oRPC.

Что такое oRPC и почему это важно?

oRPC — это не просто очередная библиотека, это целая философия построения API, которая делает акцент на типобезопасности от начала до конца (end-to-end type safety) и первоклассной поддержке OpenAPI. Представьте, что ваш клиентский код всегда точно знает, какие данные он должен отправить на сервер и какие получит в ответ, а сервер, в свою очередь, гарантирует, что обрабатывает только валидные запросы. И всё это — с автоматически генерируемой, всегда актуальной документацией OpenAPI.

По сути, oRPC берет концепцию удаленного вызова процедур (RPC), где вы вызываете функции на сервере так, будто они локальные, и обогащает её мощью TypeScript и стандартом OpenAPI. Это значит, что вы получаете не только удобство RPC, но и все преимущества строгой типизации и стандартизированной документации. Кому это нужно? Всем, кто устал от рутины, хочет повысить надежность своих приложений и ускорить процесс разработки.

Главные козыри oRPC: Мощь в деталях

Давайте разберем, что же делает oRPC таким привлекательным:

  • Типобезопасность от и до (End-to-End Type Safety): Это, пожалуй, главная фишка. oRPC гарантирует, что типы входных данных, выходных данных и даже ошибок будут строго соблюдаться как на клиенте, так и на сервере. Вы определяете схему данных один раз, например, с помощью Zod, Valibot или ArkType, и TypeScript подхватывает её, обеспечивая автодополнение и проверку типов везде. Это минимизирует ошибки, связанные с несоответствием контрактов, и делает рефакторинг куда менее болезненным.

  • OpenAPI из коробки: Забудьте о ручном написании и обновлении OpenAPI спецификаций! oRPC автоматически генерирует полную и актуальную OpenAPI документацию на основе ваших определений API. Это не просто удобно, это критически важно для больших команд и проектов, где консистентность документации — залог успеха. Ваша документация всегда будет отражать реальное состояние API.

  • Контракт-первый подход (Contract-First Development): Если вы любите сначала четко определить, как будет выглядеть ваш API, прежде чем погружаться в реализацию, oRPC поддерживает этот подход. Вы можете сначала описать контракт, а затем уже заниматься его реализацией, что способствует более продуманному дизайну и лучшему взаимодействию между командами.

  • Интеграции с фронтенд-фреймворками: oRPC не оставляет фронтенд-разработчиков в стороне. Он предлагает бесшовную интеграцию с популярными библиотеками для управления состоянием и запросами, такими как TanStack Query (для React, Vue, Solid, Svelte, Angular), SWR и Pinia Colada. Это значит, что вы можете легко подключать API к своим компонентам, используя привычные хуки и абстракции, с полной типобезопасностью.

  • Мульти-рантайм поддержка: Современная разработка часто требует гибкости в выборе среды выполнения. oRPC прекрасно чувствует себя в разных окружениях: от классического Node.js до легковесных Cloudflare Workers, Deno и Bun. Это дает вам свободу выбора и оптимизации под конкретные нужды проекта.

Под капотом: Как oRPC достигает своей магии

Архитектура oRPC модульная и хорошо продумана. Она состоит из нескольких пакетов, каждый из которых отвечает за свою часть функциональности:

  • @orpc/contract: Для определения вашего API-контракта.
  • @orpc/server: Для реализации API на стороне сервера.
  • @orpc/client: Для потребления API на клиенте с типобезопасностью.
  • @orpc/openapi: Для генерации OpenAPI спецификаций.

Ключевую роль в обеспечении типобезопасности играют библиотеки для валидации схем, такие как Zod, Valibot или ArkType. Вы определяете структуру данных с их помощью, а oRPC использует эти определения для генерации типов и валидации данных на лету.

Давайте посмотрим на упрощенный пример, как это работает:

1. Определяем роутер с процедурами:

import { os, ORPCError } from '@orpc/server';
import * as z from 'zod';

const PlanetSchema = z.object({
  id: z.number().int().min(1),
  name: z.string(),
  description: z.string().optional(),
});

export const listPlanet = os
  .input(z.object({
    limit: z.number().int().min(1).max(100).optional(),
    cursor: z.number().int().min(0).default(0),
  }))
  .handler(async ({ input }) => {
    // Ваш код для получения списка планет
    return [{ id: 1, name: 'Земля' }];
  });

export const createPlanet = os
  .$context<{ headers: { authorization?: string } }>()
  .use(({ context, next }) => {
    // Пример простой аутентификации
    if (!context.headers.authorization) {
      throw new ORPCError('UNAUTHORIZED');
    }
    return next({ context: { user: { id: 1, name: 'Admin' } } });
  })
  .input(PlanetSchema.omit({ id: true }))
  .handler(async ({ input, context }) => {
    // Ваш код для создания планеты
    console.log(`Создана планета ${input.name} пользователем ${context.user.name}`);
    return { id: 2, name: input.name };
  });

export const router = {
  planet: {
    list: listPlanet,
    create: createPlanet,
  }
};

Здесь мы используем Zod для определения схем. Обратите внимание на .$context и .use для добавления мидлварей, например, для аутентификации.

2. Создаем сервер:

import { createServer } from 'node:http';
import { RPCHandler } from '@orpc/server/node';
import { CORSPlugin } from '@orpc/server/plugins';
import { router } from './router'; // Импортируем наш роутер

const handler = new RPCHandler(router, {
  plugins: [new CORSPlugin()]
});

const server = createServer(async (req, res) => {
  const result = await handler.handle(req, res, {
    context: { headers: req.headers }
  });

  if (!result.matched) {
    res.statusCode = 404;
    res.end('No procedure matched');
  }
});

server.listen(3000, () => console.log('Сервер слушает на 3000 порту'));

Сервер очень прост в настройке, достаточно передать ему наш роутер.

3. Создаем клиент:

import type { RouterClient } from '@orpc/server';
import { createORPCClient } from '@orpc/client';
import { RPCLink } from '@orpc/client/fetch';
import { router } from './router'; // Импортируем тот же роутер для типов

const link = new RPCLink({
  url: 'http://127.0.0.1:3000',
  headers: { Authorization: 'Bearer my-secret-token' },
});

export const orpc: RouterClient<typeof router> = createORPCClient(link);

Клиент создается на основе того же роутера, что и сервер, что и обеспечивает ту самую end-to-end типобезопасность.

4. Потребляем API на клиенте:

import { orpc } from './client';

async function main() {
  try {
    const planets = await orpc.planet.list({ limit: 5 });
    console.log('Список планет:', planets);

    const newPlanet = await orpc.planet.create({ name: 'Марс', description: 'Красная планета' });
    console.log('Создана новая планета:', newPlanet);
  } catch (error) {
    console.error('Ошибка при работе с API:', error);
  }
}

main();

И вот здесь начинается магия: ваш IDE будет подсказывать вам все доступные процедуры и их параметры, а также типы возвращаемых значений. Ошибки из-за опечаток или неверных типов просто исчезают!

5. Генерируем OpenAPI Spec:

import { OpenAPIGenerator } from '@orpc/openapi';
import { ZodToJsonSchemaConverter } from '@orpc/zod/zod4';
import { router } from './router';

const generator = new OpenAPIGenerator({
  schemaConverters: [new ZodToJsonSchemaConverter()]
});

const spec = await generator.generate(router, {
  info: {
    title: 'Planet API',
    version: '1.0.0'
  }
});

console.log(JSON.stringify(spec, null, 2));

Один вызов — и у вас есть полная OpenAPI спецификация, которую можно использовать для генерации клиентских SDK, интеграции с внешними сервисами или просто для красивой документации в Swagger UI.

Где oRPC покажет себя во всей красе?

oRPC — это универсальный инструмент, но есть сценарии, где он раскрывается по-настоящему:

  • Микросервисные архитектуры: В мире микросервисов, где множество сервисов взаимодействуют друг с другом, типобезопасность и четкие контракты становятся критически важными. oRPC помогает поддерживать порядок и снижает вероятность ошибок при интеграции.
  • Full-stack приложения: Если вы разрабатываете полноценное приложение, где фронтенд и бэкенд живут в одном репозитории (или тесно связаны), oRPC значительно упрощает их взаимодействие. Изменения в бэкенде мгновенно отражаются в типах на фронтенде, предотвращая рассогласования.
  • Проекты, требующие строгой документации: Для проектов, где актуальная и точная документация API является обязательным требованием (например, публичные API или корпоративные системы), автоматическая генерация OpenAPI — это спасение.
  • Команды, стремящиеся к высокой надежности: Если ваша команда ценит качество кода, минимизацию багов и быструю итерацию, oRPC поможет достичь этих целей, устраняя целый класс ошибок, связанных с типами и контрактами.

Вердикт: Стоит ли дать oRPC шанс?

На мой взгляд, oRPC — это очень перспективный проект, который решает реальные проблемы разработчиков. Он берет лучшие идеи из tRPC и ts-rest, добавляет первоклассную поддержку OpenAPI и предлагает гибкость в выборе рантайма. Если вы работаете с TypeScript и устали от рутины при создании API, если вам важна типобезопасность от клиента до сервера и всегда актуальная документация, то oRPC определенно заслуживает вашего внимания.

Он поможет вам писать более надежный код, ускорит разработку и сделает взаимодействие между фронтендом и бэкендом гораздо более приятным. Загляните в документацию и попробуйте его в своем следующем проекте — возможно, это именно то, что вы так долго искали!