Saltare al contenuto principale
Sviluppo Mobile

OpenAPI TypeScript: Genera tipi, clienti e validazione

Scopri come la generazione OpenAPI TypeScript funziona da capo a piedi. Genera tipi, collega clienti, valuta in esecuzione e invia in modo sicuro da CI.

OpenAPI TypeScript: Genera tipi, clienti e validazione

Puoi riconoscere il momento in cui un API pipeline inizia a mentire alla squadra. Un schema cambia, gli tipi generati vengono aggiornati senza problemi, il PR diventa verde, e poi qualcuno nel front-end continua a leggere la vecchia forma di risposta perché il wrapper ha nascosto l'errore. È il problema OpenAPI TypeScript, non se un generatore può produrre interfacce.

La domanda utile è più difficile. Qual è il contratto che desideri tra schema, trasporto e validazione, e quali parti dovrebbero fallire rapidamente nel tempo di costruzione invece di filtrarsi nel tempo di esecuzione? OpenAPI TypeScript Come scelta della pipeline, le contrapposizioni diventano molto più chiare, e gli strumenti smettono di pretendere di essere la soluzione completa.

Perché i tipi generati non sono gli stessi di un __CAPGO_KEEP_0__ sicuro

Perché i tipi generati non sono gli stessi di un API sicuro

Un collega unisce un PR che aggiunge un campo di risposta facoltativo. Il file generato si aggiorna pulitamente, la diff sembra noiosa e tutti proseguono. Poi il front end continua a leggere una forma più vecchia attraverso un wrapper manuale che era 'temporaneamente' castato con as anye la produzione inizia a comportarsi come se il contratto non fosse mai cambiato.

Quello è il tranello con i tipi generati. TypeScript può proteggere solo il code che consuma i tipi generati, e solo se il layer di trasporto non cancella nuovamente il contratto. La parte OpenAPI ti dà uno schema, non una garanzia che ogni chiamante lo rispetti. La discussione sull'intelligenza delle API è utile qui perché spinge la conversazione lontano da un singolo strumento e verso come i sistemi si connettono.

Dove le fallite si nascondono

I punti di rottura più comuni sono noiosi, non esotici. Lo schema si allontana si verifica quando lo spec OpenAPI e il servizio in esecuzione smettono di corrispondere. La copertura parziale si manifesta quando uno spec modella solo il percorso felice, mentre l'app dipende da casi d'uso non documentati. Le coperture a mano sono spesso dove i tipi si indeboliscono, specialmente quando qualcuno vuole "muoversi velocemente" e utilizza any o una risposta flessibile.

Regola pratica: se il wrapper può mentire, il generatore non può salvarti.

Ci sono anche delle lacune di runtime. I tipi TypeScript scompaiono dopo la compilazione, quindi non possono rifiutare JSON malformato che arriva via cavo. La rete non si cura di cosa il tuo editor ha inferito, e questo è il motivo per cui un client generato è solo una sola layer in una pipeline più sicura API.

La domanda operativa più ampia è la sicurezza e la disciplina contrattuale, non solo la comodità dello sviluppatore. Se desideri una visione strutturata di come API contratti si inseriscono in un ciclo di vita dell'applicazione più ampio, questa guida interna sui API standard di sicurezza per la conformità agli store di app è un utile compagno.

La forma matura di pensare a OpenAPI per TypeScript è questa. Ti dà un ponte schema-tipi rigoroso, che è eccellente, ma non valuta le richieste, non impone la forma del payload di runtime, o non ferma un wrapper sciatto che mina tutto. Il generatore è il 20 percento facile. Il resto è progettazione della pipeline, e questo è dove le squadre guadagnano fiducia o accumulano falsa fiducia.

Generazione di tipi TypeScript da una spec OpenAPI

Screenshot da https://openapi-ts.dev

La configurazione più leggera e utile è spesso quella che sopravvive ai cambiamenti reali del repository. Mantenere la specifica OpenAPI nello stesso repository, generare un file di tipo commesso e rendere visibile la deriva in CI al posto di affidarsi a qualcuno che ricordi un passo di aggiornamento. Un comando come npx openapi-typescript ./openapi.yaml -o ./src/types/api.d.ts dà un file di output deterministico che i revisori possono esaminare come qualsiasi altro cambiamento di origine.

Le bandiere che contano effettivamente

The -o il flag di output è importante perché rende esplicito l'artefatto generato. --immutable è utile quando si desidera che i tipi generati preservino l'intento readonly nell'output, e --alphabetize mantiene le differenze stabili quando cambia l'ordine dello schema senza significato semantico. --enum La documentazione del progetto è chiara sullo scopo, è un

La documentazione del progetto è chiara sullo scopo, è un tipo generatore, not a client runtime or request layer, and that limitation helps when you want a lightweight, type-first setup. Its repository also shows the maintenance model behind the tool, which is part of why open source tooling can hold up in production when the docs and releases stay active, as discussed in Il caso per la manutenzione open source. Una lettura pratica su quella posizione è il progetto's repository del GitHub e documentazione del CLI.

La generazione di cavi package.json così il comando vive accanto agli altri script di costruzione, quindi eseguilo ogni volta che cambia lo spec. In CI, rigenera il file e fallisci se git diff mostra la deriva. Ciò trasforma le modifiche al contratto in lavoro di revisione visibile anziché rischio runtime silenzioso.

La parte dello schema conta quanto la riga di comando. Il progetto raccomanda compilerOptions.noUncheckedIndexedAccess così additionalProperties diventano T | undefined, che costringe un'indicizzazione più sicura nei siti di chiamata. Raccomanda inoltre di utilizzare oneOf da solo anziché mescolarlo con composizione aggiuntiva, e di mantenere $defs alla radice quando la posizione è ambigua, perché le definizioni mal posizionate possono scomparire dall'output generato. Un altro dettaglio salva tempo in seguito, openapi-typescript non produrrà mai any, quindi la mancanza di dettagli dello schema viene evidenziata presto anziché essere nascosta sotto tipi permissivi.

Mantieni lo spec esplicito, o il generatore esporrà fedelmente l'ambiguità di nuovo a te.

Il workflow che resiste è semplice. Metti lo spec sotto controllo di versione, rigenera alla costruzione, commetti il file generato e lascia che il controllore di tipo si lamenti prima che qualcuno unisca una disallineamento. Questo ti dà un contratto di confine stabile per il resto della pipeline.

Scegliere tra Tipi puri, Clienti completi e Nessun codice generato

Modello Build time File di output Peso del pacchetto Best fit
Tipi puri con un wrapper sottile Fast Veloci Basso Teams that want control and small runtime surface
Codifica del client full Più lento Molti Alto Le squadre che desiderano un handoff rapido e operazioni generate automaticamente
Nessun costruttore di richieste di codifica Velocissimo Nessuno o minimo Basso Applicazioni monobase con logica di trasporto scritta a mano

La scelta non è davvero 'quale strumento vince'. È piuttosto quale forma di pipeline si adatta al tuo repository, al tuo team e a quanto cambiamento il API subisce. 75.000 linee, 2 MB, e circa 1.200 operazioni, openapi-typescript output generato in circa 1,5 secondi in media, rispetto a circa 8,0 secondi per @hey-api/openapi-ts, 5,5 secondi per Orvale 18,1 secondi per Kubb, mentre produce anche un singolo file di output rispetto a 16 per hey-api, 2,719 per Orval, e 3,877 per Kubb (dettagli di benchmark).

Tipi puri favoriscono il controllo

Una configurazione di tipi puri si abbina bene con un layer di richiesta manuale perché puoi mantenere il runtime piccolo e la superficie del API noiosa. Ciò è importante nei front-end sensibili al bundler e nelle app in cui un team possiede sia la spec sia il consumatore. Se hai bisogno di un ricordo che l'esperienza del developer non è solo zucchero di sintassi, l' l'angolo dell'esperienza del developer è più facile da giudicare quando il tuo client code è breve, ovvio e revisionabile.

Clienti completi favoriscono la velocità di passaggio

openapi-generator, hey-api, Orval, e Kubb tutti cercano di fare di più delle tipologie. Ciò può essere utile quando si desidera generare insieme metodi di richiesta, modelli e impianti, soprattutto in un grande passaggio di consegne tra team backend e frontend. Il costo è evidente nel benchmark sopra, più file generati, più superficie di esecuzione e più spazio per la frizione di costruzione a mano a mano che la spec cresce.

No codegen favorisce i refactoring locali

Costruttori di richieste tipizzati e fetch coperture funzionano bene quando un codice di base possiede entrambe le estremità della forma e i API cambiamenti sono coordinati strettamente. Il danno è la disciplina di manutenzione. Più team e repository si trovano tra produttore e consumatore, più probabile è che una layer di richiesta manuale si allontani a meno che non si impongano test di contratto aggressivamente.

Il punto di decisione centrale non è ideologico. Se il budget del pacchetto è stretto, i tipi puri sono attraenti. Se il team desidera una scaffolding massima e può assorbire l'output, i clienti completi riducono il tempo di configurazione. Se si desidera minimizzare le parti in movimento e si può mantenere il contratto vicino, i costruttori di richieste senza codigen possono essere la scelta interna giusta.

Alimentare un Client Sottile Tipizzato intorno a Fetch o Axios

Un diagramma che illustra il processo di un Wrapper Client Tipizzato utilizzando definizioni TypeScript generate per richieste web API.

Un wrapper sottile è dove il generatore si ferma e il tuo'applicazione code inizia. Il wrapper dovrebbe esporre una funzione per operazione, accettare parametri e oggetti di query tipizzati e inviare la chiamata a fetch o un'istanza iniettata axios senza cercare di essere troppo astuto. In molti setup di produzione, quel layer rimane intorno 30–60 linee perché i tipi generati già contengono la maggior parte della forma.

Ecco il modello mentale che tiene:

  • I parametri di percorso rimangono tipizzati così /users/{id} non possono essere chiamati senza un id.
  • Gli oggetti di query rimangono tipizzati così i filtri facoltativi non si trasformano in zuppa di stringhe.
  • I corpi delle risposte rimangono tipizzati così la parsing di code può fidarsi della forma stretta che si aspetta.

Un wrapper come quello è intenzionalmente noioso. Non dovrebbe inventare ritentativi, trasformazioni o politiche di autenticazione se appartengono altrove. Dovrebbe spostare la richiesta da un'operazione tipizzata nel layer di trasporto e poi restituire il risultato tipizzato verso l'alto.

Mantieni il wrapper noioso e leggero di dipendenze, altrimenti ogni futura modifica al codice generato si ripercuoterà sull'app.

L'errore comune è patchare le incoerenze con as any quando i tipi generati non coincidono con la firma dell'interfaccia vecchia. Ciò garantisce un build verde e un'app fragile. Ciò nasconde anche la rottura del contratto che volevi che il generatore rivelasse.

Per team che preferisce Axios, il pattern rimane lo stesso, cambia solo l'implementazione del trasporto. Per team che desiderano una code più semplice sul lato client. fetch è spesso sufficiente. La parte importante è che la funzione di richiesta accetta il tipo di percorso generato e restituisce una risposta tipizzata, non un oggetto con forma lassa che viene massaggiato in seguito.

Se utilizzi bene questo punto di interconnessione OpenAPI per TypeScript ti da una divisione pulita del lavoro. La schema vive nella spec, il trasporto vive nell'interfaccia, e l'app vede operazioni tipizzate al posto di richieste ad hoc code.

Aggiungere la Validazione Runtime con zod, ajv o io-ts

I tipi TypeScript scompaiono in fase di esecuzione, e la rete non si cura della fiducia del tuo editor. Quindi il pattern sicuro non è 'generare tipi e sperare', è 'generare tipi, poi validare all'orizzonte dove i dati non verificati entrano nell'app'. Lo schema generato rimane la fonte di verità, e le librerie di validazione come zod, ajve io-ts gestiscono i controlli di confine che i tipi di compilazione non possono.

Valida dove i dati entrano

Per le app React, l'orizzonte è di solito subito dopo che la richiesta si risolve e prima che il payload entra nello stato. Per i server, è prima che il payload venga scritto in un database o consegnato a una regola commerciale. La regola è semplice, tieni la validazione vicina al confine e non disperdi controlli manuali attraverso le feature code.

A zod La forma può riflettere la forma della risposta generata senza sostituirlo:

import { z } from "zod";

const WeatherForecastSchema = z.object({
  date: z.string(),
  temperatureC: z.number(),
  summary: z.string().nullable(),
  temperatureF: z.number().optional(),
});

Quell'esempio verifica i campi che lo schema ha segnalato come facoltativi, e mantiene la verifica runtime allineata con ciò che il generatore ha prodotto. ajv è una scelta forte quando si desidera una validazione JSON Schema ad alta velocità sul server, mentre io-ts si adatta ancora a team che già vivono nel fp-ts stile di composizione.

La grande falla è la validazione troppo tardi. Se il payload attraversa l'app prima, il sistema di tipi è già stato bypassato e il bug ha un posto dove nascondersi. Una breve guida sui test di unità per JavaScript si abbina bene con questo mindset, perché sia i test di unità che la validazione dei confini funzionano meglio quando catturano le cattive assunzioni presto.

La stratificazione pulita è predittiva. OpenAPI TypeScript genera il contratto, il validatore controlla il payload runtime, e la tua app code vede solo i dati che sono sopravvissuti a entrambe le fasi. Quello è un confine molto migliore di fidarsi di un tipo statico per polizia una risposta non affidabile.

Implementare Generazione, Validazione e Test del Contratto nella CI

Screenshot da https://github.com

Un flusso che resiste trasforma il contratto in una porta, non in una raccomandazione. Regenera i tipi, falli se c'è un allontanamento, esegui tsc --noEmit, e esercita la forma API contro uno strumento di mock o di contratto prima della fusione. Se blocchi la versione del generatore in package.json, due ingegneri non possono produrre output diversi a partire dalla stessa specifica.

Una semplice forma GitHub Actions

Un flusso di lavoro pratico assomiglia a questo:

  1. Recupera la specifica dal repository o dalla fonte generata.
  2. Regenera i tipi.
  3. Falla il lavoro se git diff mostra cambiamenti.
  4. Run tsc --noEmit.
  5. Esegui un test di contratto contro un server di mock come Prism o un controllo supportato da Spectral.

Il principale punto di differenza tra i test di contratto e i test di snapshot è lo scopo. I snapshot spesso ti dicono che il file è stato modificato. I test di contratto ti dicono se la forma continua a comportarsi come dice la specifica.

Un server di mock è particolarmente utile quando il lavoro back-end e front-end sono separati da barriere di tempo o di team. Dà al consumatore code una superficie prevedibile API mentre controlla il contratto reale invece di un fixture hard-codificato. Guida di configurazione della integrazione continua è una utile guida se il tuo team ha ancora bisogno di una baseline CI pulita e ripetibile.

Pennare la versione del generatore evita uno dei fallimenti più fastidiosi nelle pipeline di generazione del codice, la deviazione di output invisibile. Se un developer aggiorna localmente il generatore e un altro no, il file generato può diventare una fonte di rumore casuale invece di segnale. La CI dovrebbe rendere impossibile ciò.

Il risultato è una pipeline in cui le modifiche dello schema, la generazione dei tipi, i controlli del compilatore e i test di contratto si rafforzano a vicenda. È questo che rende il workflow onesto.

Pipelines Mantenibili, Prestazioni e Checklist finale

Una checklist che mostra quattro passaggi chiave per mantenere una pipeline OpenAPI TypeScript per progetti di sviluppo software.

Le pipeline che sopravvivono sono quelli con una governance noiosa. Versiona lo spec, esamina le modifiche allo schema come code, blocca il generatore e documenta come le modifiche che rompono le regole vengono approvate. Se il processo è vago, le persone lo aggireranno e poi i tipi generati diventeranno decorazione invece di essere un'implementazione.

Alcuni leve di prestazione hanno effettivamente importanza

La generazione incrementale aiuta nei monorepos dove lo spec cambia spesso ma solo un pacchetto lo consuma. tsc --incremental Si può eliminare il lavoro ripetuto del compilatore e disabilitare le bandiere di output che non si hanno bisogno nelle costruzioni di produzione per mantenere la superficie generata più piccola. In pratica, il maggior vantaggio è ancora sociale, non tecnico, perché un pipeline prevedibile viene eseguito più spesso di uno astuto.

La checklist seguente è quella da tenere vicina:

  • Pinning della versione: Blocca la openapi-typescript versione in package.json così l'output non si allontana tra le macchine.
  • Revisione dello schema: Tratta le modifiche allo spec come modifiche al contratto revisionabili, non come manutenzione.
  • Detezione del drift: Regenera in CI e falli in caso di differenza.
  • Validazione Edge: Analizza i payload non affidabili prima che raggiungano lo stato dell'applicazione o la persistenza.
  • Test di contratto: Esegui un controllo con un mock che dimostra che il consumatore code rispetta lo schema.
  • Politica di cambiamento di versione: Descrivi chi approva i cambiamenti di forma e come i clienti vengono informati.

Una pipeline che include questi gate non genera solo tipi, ma rende il contratto visibile. Questa visibilità è ciò che impedisce alle squadre di fidarsi di un file che sembra sicuro.

Se stai distribuendo applicazioni Capacitor o Electron e vuoi che il tuo flusso di aggiornamento si comporti con la stessa disciplina, Capgo ti offre un modo pratico per applicare modifiche JavaScript, CSS, copia, configurazione e asset velocemente senza dover attendere la revisione dell'app store. Visita Capgo vedere come i suoi pacchetti firmati, la protezione del rollback e i controlli di rilascio si integrano in un processo di rilascio che richiede velocità senza perdere il controllo.

Aggiornamenti in tempo reale per le Capacitor app

When a web-layer bug is live, ship the fix through Capgo instead of waiting days for app store approval. Users get the update in the background while native changes stay in the normal review path.

Supporto umano da Martin

Inizia subito

Ultimi dalla nostra Blog

Capgo vi offre le migliori informazioni che avete bisogno per creare un'app mobile davvero professionale.