Maak kennis met Forge: de open source generatiepipeline voor SDK’s, CLI’s, documentatie en meer

Dimitri Mitropoulos, Matt “TK” Taylor en Samuel Macleod

7 minuten leestijd

Dit artikel is ook beschikbaar in English, Deutsch, Español, Español (Latinoamérica), Français, Italiano, 日本語, 한국어, 繁體中文, 简体中文 en Português.

Vandaag introduceren we Forge, een frisse aanpak voor het genereren van SDK’s, CLI’s, documentatie en bibliotheken. Forge is een open-source generatiepipeline die modulair uitbreidbaar is en die iedereen gratis kan implementeren en uitvoeren.

Forge staat nog in de kinderschoenen, maar genereert al de output die nodig is voor de cf CLI, en de komende maanden zal het de API-documentatie, SDK’s en nog veel meer van Cloudflare aandrijven.

We hebben Forge gebouwd omdat we het zelf nodig hadden om agents als onze klanten te behandelen. Nu maken we het open source, omdat we vinden dat iedereen alle oppervlakken moet kunnen genereren die agents nodig hebben. Vroeger hadden alleen ontwikkelaarsproducten CLI’s, API SDK’s en MCP-servers nodig, elk met geweldige bijbehorende documentatie. Nu zijn dit minimumvereisten voor elk product.

Onze API is onze generators ontgroeid

De API van Cloudflare heeft meer dan 3.500 operaties, en de honderden diensten die deze API’s aandrijven, zijn geschreven in vele talen, waaronder Rust, Go, TypeScript en Python. Toen we begonnen met het bouwen van een CLI voor de volledige Cloudflare-API, inclusief onze SDK’s en API-documentatie, hadden we een codegeneratie-pipeline nodig die deze schaal aankan. Die pipeline moet flexibel genoeg zijn om te werken in alle talen en aan te sluiten bij de werkwijze van elk van onze engineeringteams.

We hadden een manier nodig om de coördinatie-overhead tussen teams te verminderen. Wanneer een Cloudflare-productteam een API-wijziging doorvoert, moeten ze een voorbeeldbuild kunnen gebruiken van de Cloudflare-brede CLI, SDK en documentatiesite die gegenereerd worden, voordat ze die wijziging samenvoegen en naar klanten uitrollen. We hadden een manier nodig om ervoor te zorgen dat ze de generatiepipeline niet per ongeluk zouden breken. En we hadden een systeem nodig dat we konden uitbreiden om meer dan alleen een SDK te genereren, van Cap'n Web tot MCP en verder.

We hadden iets nodig dat een preview genereerde voor elke pull request, in honderden repositories.

We hebben verschillende gehoste producten geprobeerd die dit proberen op te lossen en hebben sommige in productie gebruikt. Geen van hen loste dit probleem voor ons op, en sommige zijn volledig stopgezet. Een team zou een wijziging samenvoegen die per ongeluk de generatiepipeline zou breken, een ander team zou dit ontdekken bij de release, en we hebben te veel tijd besteed aan zwemmen tegen de stroom in door gehoste tools die we niet konden controleren, en aan het coördineren van wijzigingen tussen teams en leveranciers.

Zo begonnen we Forge te bouwen.

Forge wil al deze problemen oplossen: het draait in CI, op de API-repo's van elk team, net als onze AI-codereviewer en testpipelines. Het controleert elke wijziging op fouten, en genereert vervolgens voorbeeldbuilds van de CLI, documentatie en SDK’s met alleen jouw wijzigingen uitgelicht, die je kunt installeren om te testen. Het is hetzelfde principe als Workers Previews: een volledige voorbeeldbuild voor elke wijziging, maar toegepast op SDK-generatie op schaal, inclusief wanneer het API-oppervlak verdeeld is over honderden diensten en repositories. Dat is wat Forge wil leveren.

Forge helpt je problemen in CI op te sporen voordat ze verderop in het proces problemen veroorzaken.

Forge-transformers kunnen alles genereren, inclusief Cap'n Web

Cloudflare heeft meer redenen dan de meeste anderen om een generator te willen die ver voorbij de gebruikelijke taalspecifieke doelen kan gaan. Cap’n Web is het RPC-systeem van Cloudflare waarmee TypeScript een externe API kan aanroepen alsof het een lokale methode aanroept.

// 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 maakt het mogelijk om een OpenAPI-specificatie te nemen en Cap'n Web direct te genereren. Dit opent de deur voor het genereren van bindings van Workers naar andere API's. Bindings in de Workers-runtime zijn immers geïmplementeerd als Workers die RPC-methoden blootstellen.

Dit is niet specifiek voor Cap'n Web: andere populaire tools waarop je misschien al vertrouwt hebben hetzelfde nodig. Als je TanStack Query gebruikt, zou je idealiter TanStack Query-bindings voor je applicatie willen genereren, rechtstreeks gebouwd vanuit je eigen API. Altijd up-to-date, altijd gevalideerd tegen je echte API. Hetzelfde geldt voor het genereren van Zod- of Valibot-schema's, MCP-servers, of alles wat het gemakkelijker maakt je API te gebruiken.

Dit is mogelijk omdat de codegenerators van Forge flexibel zijn. Ze zijn gebouwd om informatie van de ene output naar de andere te laten stromen.

De oorspronkelijke OpenAPI-definitie is ingebouwd in de TypeScript SDK, die wordt gebruikt om de cf CLI- en Cap'n Web-specificaties te genereren.

Forge-transformers kunnen worden geketend: outputs genereren uit andere outputs

We hebben Forge ontworpen om modulair uitbreidbaar te zijn en veel input- en outputtypen te ondersteunen. Forge biedt CLI-, SDK- en documentatiegenerators, maar niets weerhoudt je ervan een transformer toe te voegen die een bibliotheekspecifiek pakket of zelfs een volledig dashboard of applicatie genereert. Forge ondersteunt vandaag OpenAPI als invoertype, maar we hebben het ontworpen om in de toekomst AsyncAPI, GraphQL, Cap'n Proto, Protobuf of andere invoerformaten toe te staan.

Dit gaat verder dan alleen compatibiliteit: je kan er doelen mee ketenen, waarbij de output van één doel wordt gebruikt om anderen te produceren. Dit is gebruikelijk bij andere generators waarbij de CLI- en Terraform-doelen worden geproduceerd vanuit de Go SDK. Maar wat ontbreekt, en wat Forge biedt, is een manier voor de gebruiker om dit ketensysteem zelf te beheren.

Forge kan doelen aan elkaar koppelen om nieuwe resultaten te genereren.

We hadden hier zelf een oplossing voor nodig, omdat onze eigen cf CLI is geschreven in TypeScript, wat andere SDK-generators doorgaans niet als uitgangstype gebruiken voor CLI’s. Maar onze eigen situatie deed ons het diepere probleem inzien: waarom zou een SDK-generatortool deze beslissing voor jou nemen? Misschien ben je een Python-team en wil je dat de CLI in Python is.

Als je denkt 'Nou, wie maakt het uit of het in Python is of niet? De code wordt toch automatisch gegenereerd', is dat omdat CLI’s anders zijn. CLI’s introduceren vaak lokale gedragingen die niet logisch zouden zijn in een SDK. Gedragingen die je met de hand schrijft omdat ze inherent niet worden ondersteund door een API-aanroep. De cf CLI heeft bijvoorbeeld commando's zoals cf dev en cf build die bovenop de rest van de gegenereerde output worden toegevoegd. Deze commando's moeten TypeScript-APIs aanroepen uit andere pakketten zoals Vite.

Laten we nu documentatie aan de mix toevoegen. Als je je CLI en je documentatie puur genereert vanuit je OpenAPI-specificatie, hoe voer je die handgeschreven commando's dan terug in je documentatie, zodat ze naast de rest gedocumenteerd kunnen worden?

We konden geen bestaande tool vinden die dit vandaag doet, en toch is dit precies wat we nodig hebben voor cf. Dus bouwen we het in Forge.

Je API wijzigen zonder gebruikers te breken

Forge bereidt ons ook voor op beter API-versiebeheer. De v4-API van Cloudflare is al 10 jaar de ene grote hoofdversie van onze API. Sindsdien lijkt het alsof we geen nieuwe hoofdversies hebben uitgebracht, maar volgens SemVer-definities hebben we nogal wat wijzigingen doorgevoerd die een nieuwe hoofdversie waard zijn. Tegelijkertijd hebben meerdere operaties in onze API interne 'v2'-tags of 'beta'-identifiers die het betreffende deel van de productlevenscyclus al lang overleefd hebben.

Na zo vele jaren van onze v4-API zijn we ons er goed van bewust dat een grote nieuwe v5 veel van onze klanten achter zou laten. Daarom werken we, terwijl Forge onderweg artefacten uitbrengt, aan een API-versiebeheeraanpak die ons in staat stelt nieuwe grote API-versies te releasen zonder oude clients of SDK’s te breken.

We zullen binnenkort meer delen over onze SDK’s, waaronder TypeScript, Rust, Python, Go, PHP en Terraform. Terraform in het bijzonder. We weten dat het upgraden van een Terraform-provider zijn eigen zorgvuldigheid vereist, en we gaan extra aandacht besteden aan de Terraform-overgang.

Essentiële tools moeten voor iedereen toegankelijk zijn

Wij geloven dat het bouwen van tools voor API's een kernonderdeel is van het Internet, en je zou dat moeten kunnen doen zonder een SaaS-product nodig te hebben. Je zou eigenaar moeten zijn van je SDK’s, CLI’s en documentatie. En als je ze genereert, zou je er mee moeten kunnen doen wat je wilt, waar je maar wilt, gratis.

Daarom maken we Forge beschikbaar als open source onder de permissieve Apache 2.0-licentie. We willen dat mensen zich bij ons op dit traject aansluiten en bijdragen.

Of misschien niet? Misschien wil je alles voor jezelf houden. Doe het gewoon! Je kunt Forge zelf uitvoeren voor elk doel, met eigen aanpassingen, gratis en in alle discretie.

Dankwoord: Dit project is mede mogelijk gemaakt door het ontwerp en de uitvoering van Dan Carter, Steven Chong, Krishna Paritala en Shelley Jones.