Vi presentiamo Forge: la pipeline open source per generare SDK, CLI, documentazione e altro ancora

Dimitri Mitropoulos, Matt “TK” Taylor e Samuel Macleod

Lettura di 7 min

Questo post è disponibile anche in English, Deutsch, Español, Español (Latinoamérica), Français, 日本語, 한국어, 繁體中文, 简体中文, Português e Nederlands.

Oggi presentiamo Forge, un approccio rinnovato alla generazione di SDK, CLI, documentazione e librerie. Forge è una pipeline di generazione open source, modulare ed estensibile, che chiunque può distribuire ed eseguire gratuitamente.

Forge è ancora ai suoi albori, ma genera già l’output necessario per la CLI cf e nei prossimi mesi alimenterà la documentazione API, gli SDK e molto altro di Cloudflare.

Abbiamo costruito Forge perché ne avevamo bisogno noi stessi, per trattare gli agenti come nostri clienti. Ora lo pubblichiamo come open source perché crediamo che tutti debbano poter generare tutte le superfici di cui gli agenti hanno bisogno. In precedenza, solo i prodotti per sviluppatori richiedevano CLI, SDK per API e server MCP, tutti con un’ottima documentazione. Ora queste sono le condizioni minime per qualsiasi prodotto.

La nostra API ha superato i nostri generatori

L’API di Cloudflare conta oltre 3.500 operazioni e le centinaia di servizi che le alimentano sono scritti in molti linguaggi, tra cui Rust, Go, TypeScript e Python. Nell’intraprendere la costruzione di una CLI per tutta l’API di Cloudflare, compresi i nostri SDK e la documentazione API, avevamo bisogno di una pipeline di generazione di codice in grado di operare a questa scala. Quella pipeline deve essere abbastanza flessibile da funzionare su tutti i linguaggi e adattarsi al modo di lavorare di ciascun team di engineering.

Avevamo bisogno di un modo per ridurre il carico di coordinamento tra i team. Quando un team di prodotto di Cloudflare apporta una modifica all’API, deve poter utilizzare una build di anteprima della CLI, dell’SDK e del sito di documentazione comuni a tutta Cloudflare, prima di unire quella modifica e distribuirla ai clienti. Avevamo bisogno di un modo per garantire che i team non interrompessero inavvertitamente la pipeline di generazione. E avevamo bisogno di un sistema che potessimo estendere per generare più di un semplice SDK, da Cap’n Web a MCP e oltre.

Avevamo bisogno di qualcosa che generasse un’anteprima a ogni pull request, su centinaia di repository.

Abbiamo provato diversi prodotti ospitati che cercano di risolvere questo problema e ci siamo affidati ad alcuni di essi in produzione. Nessuno ha risolto il problema per noi, e alcuni hanno chiuso del tutto. Un team univa una modifica che interrompeva inavvertitamente la pipeline di generazione, un altro la scopriva solo al momento del rilascio, e abbiamo perso troppo tempo a nuotare controcorrente attraverso strumenti hosted che non potevamo controllare, coordinando le modifiche tra team e fornitori.

Così abbiamo iniziato a costruire Forge.

Forge mira a risolvere tutti questi problemi: viene eseguito in CI, nei repository API di ciascun team, esattamente come il nostro revisore di codice AI e le pipeline di test. Esegue il lint di ogni modifica e genera poi build di anteprima della CLI, della documentazione e degli SDK con solo le tue modifiche evidenziate, che puoi installare per testarle. È lo stesso principio di Workers Previews: una build di anteprima completa per ogni modifica, applicata però alla generazione di SDK su larga scala, anche quando la superficie API è distribuita su centinaia di servizi e repository. È questo l’obiettivo di Forge.

Forge ti aiuta a individuare i problemi in CI, prima che causino inconvenienti a valle.

I transformer di Forge possono generare qualsiasi cosa, incluso Cap’n Web

Cloudflare ha più ragioni di chiunque altro per volere un generatore capace di andare ben oltre i soliti target di generazione. Cap’n Web è il sistema RPC di Cloudflare che consente a TypeScript di chiamare una API remota come se fosse una chiamata a un metodo locale:

// Authenticate, get the user's ID, fetch their profile, and fetch every friend's profile...
let authed = api.authenticate(apiToken);
let profile = api.getUserProfile(authed.getUserId());
let friends = authed.getFriendIds().map(id => api.getUserProfile(id));

// ...in a *single* request
let [me, myFriends] = await Promise.all([profile, friends]);

Forge rende possibile prendere una specifica OpenAPI e generare Cap’n Web direttamente. Questo apre la porta alla generazione di binding da Workers ad altre API. Dopotutto, i binding nel runtime di Workers sono implementati come Workers che espongono metodi RPC.

Questo non è specifico di Cap’n Web: altri strumenti popolari su cui potresti già fare affidamento hanno la stessa necessità. Se usi TanStack Query, vorresti idealmente poter generare binding TanStack Query per la tua applicazione, costruiti direttamente dalla tua API. Sempre aggiornati, sempre validati rispetto alla tua API reale. Lo stesso vale per la generazione di schemi Zod o Valibot, server MCP o qualsiasi altra cosa che renda la tua API più facile da utilizzare.

Questo è possibile perché i generatori di codice di Forge sono flessibili. Sono progettati per far fluire le informazioni da un output all’altro.

La definizione OpenAPI originale viene integrata nell’SDK TypeScript, che viene poi usato per generare le specifiche per la CLI cf e Cap’n Web.

I transformer di Forge possono essere concatenati: generare output da altri output

Abbiamo progettato Forge in modo che sia modulare ed estensibile e che supporti molti tipi di input e output. Forge fornisce generatori di CLI, SDK e documentazione, ma nulla ti impedisce di aggiungere un transformer che generi un pacchetto specifico per una libreria o persino un dashboard o un’applicazione completa. Forge supporta oggi OpenAPI come tipo di input, ma è stato progettato per consentire in futuro AsyncAPI, GraphQL, Cap’n Proto, Protobuf o altri formati di input.

Questo va oltre la semplice compatibilità: ti consente di concatenare target, usando l’output di un target per produrne altri. Questa è una pratica comune in altri generatori, dove i target CLI e Terraform vengono prodotti a partire dall’SDK Go. Ma ciò che manca, e che Forge fornisce, è un modo per permettere all’utente di controllare questo sistema di concatenazione in autonomia.

Forge può concatenare target per produrre nuovi output.

Avevamo bisogno di una soluzione per questo noi stessi, perché la nostra CLI cf è scritta in TypeScript, qualcosa che altri generatori di SDK generalmente non concatenano per le CLI. Ma la nostra situazione ci ha fatto riconoscere il problema più profondo: perché uno strumento generatore di SDK dovrebbe prendere questa decisione al posto tuo? Forse sei un team Python e vuoi che la CLI sia in Python.

Se stai pensando: “E chi se ne importa se è in Python o no? Il codice viene generato automaticamente”, il motivo è che le CLI sono diverse. Le CLI introducono spesso comportamenti esclusivamente locali che non avrebbero senso in un SDK: comportamenti che scrivi a mano perché non sono supportati da nessuna chiamata API. Ad esempio, la cf CLI ha comandi come cf dev e cf build che vengono aggiunti al resto dell’output generato. Questi comandi devono chiamare API TypeScript da altri pacchetti come Vite.

Aggiungiamo ora la documentazione all’equazione. Se generi la tua CLI e la tua documentazione puramente dalla tua specifica OpenAPI, come reintroduci nella documentazione quei comandi scritti a mano, in modo che possano essere documentati insieme al resto?

Non abbiamo trovato nessuno strumento esistente che lo faccia oggi, eppure è esattamente ciò di cui abbiamo bisogno per cf. Quindi lo stiamo integrando in Forge.

Modifica la tua API senza compromettere gli utenti

Forge ci sta preparando anche per un migliore versionamento delle API. L’API v4 di Cloudflare è l’unica versione principale della nostra API da 10 anni. Da allora, potrebbe sembrare che non abbiamo rilasciato nuove versioni principali, ma secondo le definizioni di SemVer abbiamo apportato diverse modifiche che avrebbero giustificato una nuova versione principale. Allo stesso tempo, alcune operazioni della nostra API hanno tag interni ‘v2’ o identificatori ‘beta’ che hanno ormai abbondantemente superato quella fase del ciclo di vita del prodotto.

Dopo tanti anni con la nostra API v4, siamo ben consapevoli che una grande e nuova v5 lascerebbe indietro molti dei nostri clienti. Pertanto, mentre Forge pubblica artefatti lungo il percorso, stiamo lavorando a un approccio al versionamento delle API che ci consenta di rilasciare nuove versioni principali senza compromettere i client o gli SDK precedenti.

Avremo presto molto altro da condividere sui nostri SDK, tra cui TypeScript, Rust, Python, Go, PHP e Terraform. Soprattutto Terraform. Sappiamo che l’aggiornamento di qualsiasi provider Terraform richiede un livello di rigore specifico, e presteremo particolare attenzione alla transizione di Terraform.

Gli strumenti critici devono essere aperti a tutti

Crediamo che costruire strumenti per le API sia una parte fondamentale di Internet e che chiunque debba poterlo fare senza necessitare di un prodotto SaaS. Devi essere il proprietario dei tuoi SDK, CLI e documentazione. E se li generi, devi poterli usare come vuoi, dove vuoi, gratuitamente.

Per questo rendiamo Forge disponibile come open source sotto la permissiva licenza Apache 2.0. Vogliamo che le persone si uniscano a noi in questo percorso e contribuiscano.

O forse no? Forse vuoi tenerlo tutto per te. Fai pure! Puoi eseguire Forge per qualsiasi scopo, con modifiche personalizzate, gratuitamente e in modo privato sulla tua infrastruttura.

Riconoscimenti: Questo progetto è stato reso possibile anche grazie all'impegno nella progettazione e nella realizzazione di Dan Carter, Steven Chong, Krishna Paritala e Shelley Jones.