Uno sviluppatore ha trascorso due settimane a sostituire un'API REST con tRPC in uno strumento interno.
Perché il passaggio è stato importante
Il vecchio stack ci costringeva a mantenere un DTO, un validatore e un set separato di tipi TypeScript per il frontend. Rinomina un campo nel backend e l'API continuava a restituire 200, l'interfaccia utente continuava a renderizzare e il bug appariva solo come valori "undefined". Un cliente ha individuato il problema prima di chiunque altro nel team. I contratti REST nascondevano il problema e i file extra aggiungevano una manutenzione che non ha mai portato benefici.
Com'era configurato il setup REST
- Spec OpenAPI – un file statico che descriveva gli endpoint ma non fungeva mai da unica fonte di verità.
- Fase di generazione del Client SDK – un job di CI che produceva un wrapper JavaScript.
- Collection di Postman – un artefatto di testing condiviso che nessuno usava.
- Interfacce TypeScript manuali – tipi scritti a mano che dovevano rimanere sincronizzati con il server.
Ogni modifica all'API toccava almeno tre di questi artefatti, oltre al validatore e a qualsiasi chiamata fetch a valle. Il processo era lento e soggetto a errori.
Come tRPC ha snellito il codebase
tRPC elimina il file di contratto separato. Il server esporta un tipo router; il client importa lo stesso tipo. Rinomina un campo nel backend e l'editor segnala istantaneamente l'incongruenza, senza bisogno di eseguire il codice o di una richiesta fallita. Lo sviluppatore ha eliminato:
- Il file della spec OpenAPI.
- La fase di generazione del client SDK.
- La collection di Postman inutilizzata.
- La cartella delle interfacce TypeScript manuali.
Il repository è diventato più snello e il feedback è arrivato durante lo sviluppo invece che dopo il deployment.
Limiti di tRPC
tRPC funziona solo quando entrambi gli estremi parlano TypeScript. Risulta inadeguato se:
- Un team mobile usa Swift o Kotlin.
- L'API deve essere consumata da partner esterni.
- Hai bisogno di un'interfaccia pubblica e indipendente dal linguaggio (language-agnostic).
Cosa ha richiesto effettivamente la migrazione
L'impegno di due settimane è stato molto più di un semplice copia-incolla. Lo sviluppatore ha dovuto:
- Riscrivere ogni chiamata
fetchper utilizzare le funzioni client di tRPC. - Regolare la logica di gestione degli errori.
- Aggiornare i componenti UI che facevano affidamento su stati di caricamento e di retry legati alle risposte HTTP grezze.
Domande da porsi prima di procedere
- Sia il frontend che il backend usano TypeScript? Senza un sistema di tipi condiviso, tRPC perde il suo vantaggio principale.
- Lo stesso team è responsabile di entrambi i lati? Lacune nella responsabilità possono reintrodurre il disallineamento dei contratti (contract drift).
- Stai risolvendo un bug concreto o stai inseguendo una tendenza? Il boost di produttività è reale, ma dovrebbe risolvere un problema esistente.
Un approccio ibrido per il 2025
Molti team trovano il giusto equilibrio utilizzando entrambi gli stack:
- tRPC per i layer applicativi interni, dove il codebase è interamente in TypeScript e lo stesso team gestisce sia il server che il client.
- REST per webhook, API pubbliche e integrazioni con partner, dove è richiesto un accesso indipendente dal linguaggio.
Utilizzare lo strumento giusto per ogni superficie mantiene lo sviluppo interno veloce, preservando al contempo l'apertura necessaria per i consumatori esterni.
Conclusione: Sostituire REST con tRPC può eliminare la duplicazione degli artefatti del contratto e far emergere i bug durante la fase di editing, ma i benefici si concretizzano solo quando l'intero stack condivide TypeScript e il team può assorbire il costo della migrazione. Una strategia mista permette di raccogliere i vantaggi senza escludere i consumatori che non usano TypeScript.
