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 fetch per 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.