Présentation de tRPC
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
tRPC vous offre une sécurité de typage de bout en bout entre votre serveur (Node) et votre client, sans même déclarer de types. Sur le backend, vous retournez simplement des données dans une fonction, et sur le frontend vous utilisez ces données via le nom du endpoint.
👋 Je suis Alex, alias "KATT" sur GitHub, et je souhaite vous présenter une bibliothèque nommée tRPC. Je n'ai pas encore publié d'articles à son sujet, donc j'écris cette intro pour lancer le mouvement (mais nous avons déjà dépassé >530 🌟 sur GitHub). Attendez-vous à des articles et vidéos de présentation prochainement ! Pour suivre les actualités ou poser des questions, suivez-moi sur Twitter @alexdotjs.
Voici à quoi ressemble un appel client vers un endpoint tRPC :

J'ai développé une bibliothèque pour React (@trpc/react) qui s'appuie sur l'excellent react-query, mais la librairie cliente (@trpc/client) fonctionne sans React (si vous souhaitez créer une lib spécifique pour Svelte/Vue/Angular/[..], contactez-moi !).
Aucune génération de code n'est requise et vous pouvez l'intégrer facilement à votre projet Next.js/CRA/Express existant.
Exemple
Voici un exemple de procédure tRPC (endpoint) nommée hello qui prend un argument de type string.
tsxconst appRouter = trpc.router().query('hello', {input: z.string().optional(),resolve: ({ input }) => {return {text: `hello ${input ?? 'world'}`,};},});export type AppRouter = typeof appRouter;
tsxconst appRouter = trpc.router().query('hello', {input: z.string().optional(),resolve: ({ input }) => {return {text: `hello ${input ?? 'world'}`,};},});export type AppRouter = typeof appRouter;
Et voici un client utilisant ces données de manière type-safe :
tsximport type { AppRouter } from './server';async function main() {const client = createTRPCClient<AppRouter>({url: `http://localhost:2022`,});const result = await client.query('hello', '@alexdotjs');console.log(result); // --> { text: "hello @alexdotjs" }}main();
tsximport type { AppRouter } from './server';async function main() {const client = createTRPCClient<AppRouter>({url: `http://localhost:2022`,});const result = await client.query('hello', '@alexdotjs');console.log(result); // --> { text: "hello @alexdotjs" }}main();
C'est tout ce dont vous avez besoin pour la sécurité de typage ! Le result est inféré à partir des données retournées par la fonction backend. Les données d'entrée sont également inférées via le validateur, donc les données sont immédiatement exploitables - en réalité, vous devez passer les données d'entrée via un validateur (& tRPC fonctionne nativement avec zod/yup/validateurs personnalisés).
Lien CodeSandbox pour expérimenter l'exemple : https://githubbox.com/trpc/trpc/tree/main/examples/standalone-server (privilégiez la sortie terminal plutôt que l'aperçu !)
Quoi ? J'importe du code backend dans mon client ? - Non, absolument pas
Bien que cela y ressemble, aucun code n'est partagé du serveur vers le client ; le import type de TypeScript "[...] importe uniquement des déclarations pour les annotations et définitions de types. Il est toujours entièrement effacé, sans laisser de trace à l'exécution." - une fonctionnalité ajoutée dans TypeScript 3.8 - voir la doc TypeScript.
Aucune génération de code n'est impliquée, vous pouvez l'ajouter à votre application dès aujourd'hui tant que vous avez un moyen de partager les types entre serveur et client (un monorepo est idéal).
Mais ce n'est que le début !
J'ai mentionné précédemment une bibliothèque React. Pour utiliser les données ci-dessus dans React :
tsxconst { data } = trpc.useQuery(['hello', '@alexdotjs']);
tsxconst { data } = trpc.useQuery(['hello', '@alexdotjs']);
.. et vous obtiendrez des données type-safe côté client.
Vous pouvez intégrer tRPC dès maintenant à votre projet brownfield existant (des adaptateurs existent pour Express/Next.js). Cela fonctionne parfaitement avec CRA et devrait aussi marcher avec React Native. La solution n'est même pas liée à React : si vous voulez développer une lib pour Svelte ou Vue, contactez-moi.
Quid des mutations de données ?
Les mutations sont aussi simples que les requêtes - elles reposent sur le même mécanisme sous-jacent mais sont exposées différemment pour plus de clarté syntaxique et génèrent une requête HTTP POST plutôt qu'un GET.
Voici un exemple un peu plus complexe utilisant une base de données, tiré de notre démo TodoMVC sur todomvc.trpc.io / https://github.com/trpc/trpc/tree/main/examples/next-prisma-todomvc
tsxconst todoRouter = createRouter().mutation('add', {input: z.object({id: z.string().uuid(),data: z.object({completed: z.boolean().optional(),text: z.string().min(1).optional(),}),}),async resolve({ ctx, input }) {const { id, data } = input;const todo = await ctx.task.update({where: { id },data,});return todo;},});
tsxconst todoRouter = createRouter().mutation('add', {input: z.object({id: z.string().uuid(),data: z.object({completed: z.boolean().optional(),text: z.string().min(1).optional(),}),}),async resolve({ ctx, input }) {const { id, data } = input;const todo = await ctx.task.update({where: { id },data,});return todo;},});
Et l'utilisation avec React ressemble à ceci :
tsxconst addTask = trpc.useMutation('todos.add');return (<><inputplaceholder="What needs to be done?"onKeyDown={(e) => {const text = e.currentTarget.value.trim();if (e.key === 'Enter' && text) {addTask.mutate({ text });e.currentTarget.value = '';}}}/></>)
tsxconst addTask = trpc.useMutation('todos.add');return (<><inputplaceholder="What needs to be done?"onKeyDown={(e) => {const text = e.currentTarget.value.trim();if (e.key === 'Enter' && text) {addTask.mutate({ text });e.currentTarget.value = '';}}}/></>)
Fin, pour l'instant.
Bref, comme je l'ai dit, je voulais juste lancer la machine. Il y a beaucoup d'autres fonctionnalités :
-
Création de contextes pour les requêtes entrantes (données utilisateur injectées dans les résolveurs) - lien
-
Support des middlewares pour les routeurs - lien
-
Fusion de routeurs (pour éviter de tout mettre dans un seul fichier) - lien
-
Le SSR le plus simple jamais vu dans l'écosystème React via notre adaptateur
@trpc/next- lien -
Formatage d'erreurs typé - lien
-
Transformateurs de données (utilisation d'objets Date/Map/Set via le réseau) - lien
-
Helpers pour React Query
Pour démarrer, consultez les exemples dans le Guide de démarrage pour Next.js.
