tRPC: лучший способ создания API в 2022 году?

[первоначально опубликовано здесь]

Мы все знаем, как сложно создавать API. Вы устанавливаете Express, или Nest, если вы разрабатываете для большого проекта, может быть GraphQL, а затем вам приходится все делать самому. От реляционного отображения до поддержки TypeScript на сервере и клиенте. Но что, если я скажу вам, что для этого есть решение «все в одном»?

Слишком хорошо, чтобы быть правдой, подумаете вы; но я пишу эту статью, чтобы сказать вам, что это не так.

Что такое tRPC?

tRPC — это, по сути, просто способ вызова кода. Думайте об этом как о конечной точке API, но на жаргоне tRPC это процедура.

«Итак, мы можем создавать API с помощью этого нового инструмента; что изменилось?».

tRPC — это не просто способ создания процедур, под капотом у него есть гораздо больше возможностей.

  • ⚡️ Быстрота — нет генерации кода или разрастания во время выполнения.
  • 🧙♂️ Типовая безопасность — от БД до клиента
  • ✅ Безопасно — Входная и выходная валидация с помощью Zod
  • 🍃 Легкий — tRPC имеет ноль деплоев (@trpc/client@9.27.0 всего 4.9kb gzipped)
  • 🔋 Батарейки включены — Доступен для React, Next, Express и Fastify (может использоваться с Nuxt & SvelteKit, но API может быть неполным)
  • ⛑ Поддержка React Query — Все запросы, мутации и подписки используют React Query.

Как это сравнивается?

REST

Недостатком REST является отсутствие стандартизации. Проще говоря, REST — это архитектурный стиль сопоставления путей URL с сущностями, а затем предоставление различных HTTP-методов для получения или изменения этих сущностей.

Этот подход интуитивно понятен большинству разработчиков, но ему не хватает стандартизации на сервере и клиенте. Думайте об этом как о воображаемой неясной линии между обеими сторонами. Не очень хорошо для DX…

GraphQL

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

Однако недостатком является то, что вам придется изучить синтаксис GraphQL и много накладных расходов при создании проекта.

Взгляд на некоторый код

Определение процедуры

Прежде всего, лучше всего определить схемы. В моем случае я буду запрашивать PokéAPI, который использует REST, поэтому я вручную определю ожидаемый ответ с помощью Zod.

const pokemonSchema = z.object({
  count: z.number(),
  next: z.string().nullish(),
  previous: z.string().nullish(),
  results: z.array(
    z.object({
      name: z.string(),
      url: z.string(),
    })
  ),
});
Вход в полноэкранный режим Выход из полноэкранного режима

Затем мы можем определить процедуру для получения покемонов с вводом смещения для постраничной сортировки.

export const pokemonRouter = createRouter().query("findAll", {
  // Create input schema
  input: z.object({
    offset: z.number(),
  }),
  async resolve({ input }) {
    const res = await (
      await fetch(`https://pokeapi.co/api/v2/pokemon?offset=${input.offset}`)
    ).json();

    // Validate the response
    return pokemonSchema.parse(res);
  },
});
Вход в полноэкранный режим Выход из полноэкранного режима

В приведенном выше примере, если входные или выходные критерии не выполняются, выдается ошибка. И все это всего за 30 строк кода!

Затем нам нужно связать pokemonRouter с основным маршрутизатором. Это также делается с помощью функции tRPC createRoute, и может быть легко добавлено с помощью .merge().

import { pokemonRouter } from "./pokemon";

export const appRouter = createRouter()
  .transformer(superjson)
  .merge("pokemon.", pokemonRouter);

export type AppRouter = typeof appRouter;
Вход в полноэкранный режим Выход из полноэкранного режима

Как вы видите, мы экспортируем тип appRouter, нам нужно сделать это, чтобы TypeScript мог вывести наши процедуры, а также для автозаполнения! Мы можем легко создать хуки для вызова нашего кода с помощью строки ниже (это необходимо только при использовании в Next или React):

export const trpc = createReactQueryHooks<AppRouter>();
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем мы можем использовать данные в компоненте следующим образом:

const Home: NextPage = () => {
  // ...

  const { data, refetch } = trpc.useQuery(["pokemon.findAll", { offset }]);

  // ...
};
Войти в полноэкранный режим Выйти из полноэкранного режима

В моем случае, поскольку я добавил пагинацию, у меня есть некоторая дополнительная функциональность, чтобы заставить ее работать. Поскольку большая часть этого функционала — React Query, я не буду приводить его здесь, но вы можете ознакомиться с исходным кодом здесь.

Мысли

В целом, я твердо убежден, что tRPC останется. По мере того, как все больше и больше предприятий будут использовать эту технологию, мы увидим более сильную экосистему и более широкую поддержку со стороны front-end и back-end фреймворков.

Если вы хотите попробовать, вы можете перейти на их сайт, чтобы узнать больше об этой технологии.

Надеюсь, это помогло 😃

Оцените статью
devanswers.ru
Добавить комментарий