cURL è la lingua franca delle API. Apri la documentazione di Stripe, GitHub, OpenAI, Twilio o di qualunque REST API seria: gli esempi di request sono quasi sempre comandi curl. È il modo più conciso e neutrale rispetto al linguaggio per descrivere una chiamata HTTP: metodo, URL, header, body. Il problema nasce quando devi passare da quell'esempio da riga di comando al codice che gira davvero dentro la tua applicazione: un fetch nel frontend, un client requests in uno script Python, una chiamata cURL in un backend PHP. Questo tool fa esattamente quella traduzione, mantenendo la semantica HTTP intatta.
Cosa interpreta il parser. Il comando viene tokenizzato rispettando le regole di quoting della shell (apici singoli, doppi, escape con backslash), poi ogni opzione viene mappata sul concetto HTTP corrispondente:
-X, --request imposta il metodo (GET, POST, PUT, PATCH, DELETE). Se manca ma è presente un body, il metodo diventa POST, esattamente come fa cURL.-H, --header aggiunge un header di request. È ripetibile: -H "Authorization: Bearer ..." -H "Content-Type: application/json".-d, --data / --data-raw / --data-binary definisce il body. Più -d vengono concatenati con &. In assenza di un Content-Type esplicito, cURL usa application/x-www-form-urlencoded.--json (cURL 7.82+) è una scorciatoia per body più Content-Type: application/json più Accept: application/json.-u, --user user:password genera l'header Authorization: Basic con la coppia codificata in base64.-b, --cookie imposta l'header Cookie.-F, --form costruisce un body multipart/form-data: -F "campo=valore" per un campo, -F "file=@percorso" per un upload.- La query string fa parte dell'URL e viene preservata così com'è.
fetch, requests, cURL PHP, Node: quattro filosofie diverse. Lo stesso comando produce codice molto diverso a seconda del target, e le differenze contano.
fetch (JavaScript) è asincrono e basato su Promise, disponibile nativamente nel browser e in Node dalla versione 18. Non serializza il JSON per te: il body va passato come stringa con JSON.stringify(...) e il Content-Type lo imposti a mano negli header. Nel browser è soggetto alle policy CORS del server di destinazione.
requests (Python) è sincrono e ad alto livello. Il parametro json= serializza il dizionario e imposta Content-Type: application/json automaticamente; data= con un dizionario produce un body form-urlencoded; files= gestisce il multipart; auth=(user, password) fa la basic auth. È il target più compatto.
La cURL di PHP (l'estensione libcurl) è imperativa e verbosa: curl_init(), una sequenza di curl_setopt() (CURLOPT_CUSTOMREQUEST, CURLOPT_HTTPHEADER, CURLOPT_POSTFIELDS, CURLOPT_USERPWD), poi curl_exec(). In cambio della verbosità offre controllo totale su TLS, timeout e redirect.
Il target Node usa la fetch globale (Node 18+), l'approccio idiomatico moderno per un client HTTP server-side, evitando il modulo https a basso livello basato su stream e callback.
Header, autenticazione e body: dove sbagliano i converter approssimativi. Un bearer token è solo un header Authorization: Bearer <token>, quindi passa dritto come header in ogni linguaggio. La basic auth invece va tradotta: cURL fa -u user:pass, ma nel codice diventa btoa() in JavaScript, base64_encode() in PHP, la tupla auth= in requests. Il body JSON va serializzato con la funzione giusta del linguaggio, non incollato come stringa grezza. Il multipart non è un semplice header: richiede FormData in JS, l'array files= in requests, un array associativo con CURLFile in PHP.
Privacy: tutto nel browser. Il comando che incolli spesso contiene token, chiavi API o password (i -H "Authorization: ...", i -u user:pass). Per questo il tool lavora interamente client-side: il parsing e la generazione avvengono in JavaScript nel tuo browser, niente viene inviato a un server. Puoi convertire comandi con segreti reali senza che lascino la macchina, anche se la regola d'oro resta sostituirli con variabili d'ambiente nel codice finale.