/api/v1
Documentazione dell’API
Una richiesta POST formatta un file. Nessuna chiave, nessun account, nessuna firma — l’indirizzo e un corpo sono tutto il contratto.
Avvio rapido
Minifica un foglio di stile e stampa il risultato:
curl --data-urlencode 'input=.card { padding: 8px; margin: 0 auto; }' \
https://formatter.nextwell.top/api/v1/minify/css/raw
# .card{padding:8px;margin:0 auto}
Sostituisci {css} con {js} o {html}, e {minify} con {beautify}. Ogni combinazione funziona.
Endpoint
L’indirizzo di base è {base}. Tutto ciò che segue è un POST, se non indicato diversamente.
| Metodo | Percorso | Scopo |
|---|---|---|
| POST | /api/v1/minify/{lang} | Minifica, risposta JSON |
| POST | /api/v1/minify/{lang}/raw | Minifica, risposta in testo semplice |
| POST | /api/v1/beautify/{lang} | Formatta, risposta JSON |
| POST | /api/v1/beautify/{lang}/raw | Formatta, risposta in testo semplice |
| GET | /api/v1/limits | Quanto resta a questo IP, senza consumare una richiesta |
| GET | /api/v1/health | Controllo di attività, mai soggetto a limiti |
{lang} è css, js oppure html.
Inviare il codice
Su ogni endpoint sono accettate tre forme di corpo — scegli quella che il tuo client rende più semplice.
Codificato come modulo
Un campo {input}, {type}. È la forma che le API di minificazione accettano per convenzione, quindi uno script esistente cambia solo indirizzo.
curl --data-urlencode 'input=body{margin:0;padding:0}' \
https://formatter.nextwell.top/api/v1/beautify/css
JSON
{type} con una stringa {input}.
curl -H 'Content-Type: application/json' \
-d '{"input":"const a=1;const b=a+1;console.log(b)"}' \
https://formatter.nextwell.top/api/v1/beautify/js
Corpo grezzo
Qualsiasi altro content type: il corpo è il codice. Comodo per {example}.
curl --data-binary @style.css \
-H 'Content-Type: text/css' \
https://formatter.nextwell.top/api/v1/minify/css
Dimensione
2 MB per richiesta. Tutto ciò che è più grande torna come 413 senza essere letto.
Parametri di query
| Nome | Valori | Significato |
|---|---|---|
engine |
auto upstream local |
Quale motore gestisce questa richiesta. {auto} — il valore predefinito — manda a monte la minificazione di CSS e JS finché dura il budget, poi ripiega in locale. {upstream} rifiuta invece di ripiegare. {local} non lascia mai il server. |
indent |
2 4 tab |
Solo per la formattazione: quanto vale un livello di indentazione. |
curl --data-urlencode 'input=.a{color:red}' \
'https://formatter.nextwell.top/api/v1/beautify/css?indent=tab&engine=local'
La risposta
Una chiamata riuscita restituisce JSON:
{
"ok": true,
"action": "minify",
"language": "css",
"engine": "upstream",
"input_bytes": 1024,
"output_bytes": 640,
"saved_bytes": 384,
"saved_percent": 37.5,
"duration_ms": 42,
"output": "p{color:red}"
}
| Campo | Tipo | Significato |
|---|---|---|
ok | boolean | Sempre true in caso di successo. |
action | string | minify o beautify — ciò che è stato richiesto. |
language | string | css, js o html. |
engine | string | upstream se se n’è occupato il servizio esterno, local se l’ha fatto questo server. |
input_bytes | number | Dimensione di ciò che è stato inviato, in byte. |
output_bytes | number | Dimensione del risultato, in byte. |
saved_bytes | number | La differenza; negativa quando si formatta. |
saved_percent | number | La stessa differenza in percentuale, con un decimale. |
duration_ms | number | Quanto è durato il lavoro, in millisecondi. |
output | string | Il codice formattato. |
Risposte in testo semplice
Aggiungi {raw} a un qualsiasi endpoint di formattazione e il corpo è il risultato e nient’altro, come {type}. Le intestazioni restano le stesse. Utile quando a chiamare è una shell:
curl -s --data-binary @app.js \
-H 'Content-Type: text/javascript' \
https://formatter.nextwell.top/api/v1/minify/js/raw > app.min.js
Intestazioni della risposta
| Intestazione | Significato |
|---|---|
X-Formatter-Engine | Quale motore ha prodotto il risultato. |
X-Formatter-Duration | Tempo di elaborazione in millisecondi. |
X-RateLimit-Remaining-Second … -Month | Quanto resta a questo IP in ciascuna finestra. |
Retry-After | Su un 429: secondi che mancano alla riapertura della finestra esaurita più stretta. |
curl -s -D - -o /dev/null --data-urlencode 'input=.a{color:red}' \
https://formatter.nextwell.top/api/v1/minify/css
Errori
Ogni errore è JSON nella forma consueta per un’API di questo tipo, quindi un client che già gestisce quella forma gestisce anche i nostri:
{
"errors": [
{ "status": 429, "title": "Too many requests", "detail": "…" }
]
}
| Stato | Titolo | Quando |
|---|---|---|
| 400 | Missing input Bad request | Nessun corpo, oppure un campo input vuoto. |
| 404 | Not found | Il percorso non esiste. |
| 405 | Method not allowed | Un endpoint di formattazione chiamato con qualcosa di diverso da POST. |
| 413 | Payload too large | Il corpo supera i 2 MB. |
| 415 | Unsupported language | Il linguaggio nel percorso non è css, js o html. |
| 422 | Malformed input | Il formattatore ha rifiutato il sorgente — di solito un errore di sintassi. |
| 429 | Too many requests | Una delle finestre di limite è esaurita. Leggi Retry-After. |
| 502 | Upstream failed | Solo con engine=upstream: il servizio esterno non ha risposto. Senza quella forzatura la richiesta sarebbe ripiegata in locale. |
| 500 | Internal error | Tutto il resto. |
Limiti di frequenza
Per indirizzo IP, cinque finestre scorrevoli, applicate tutte insieme. Una richiesta deve stare in tutte e cinque.
| Finestra | Limite |
|---|---|
| Al secondo | {n} richieste |
| Al minuto | {n} richieste |
| All’ora | {n} richieste |
| Al giorno | {n} richieste |
| Al mese | {n} richieste |
Quando una finestra è esaurita la risposta è 429 con un’intestazione Retry-After che indica i secondi mancanti alla riapertura della più stretta. Nulla viene messo in coda.
I contatori stanno in un piccolo database su disco, quindi riavviare il servizio non regala a nessuno una giornata nuova.
{endpoint} riporta lo stato attuale di tutte e cinque le finestre senza consumarne una.
curl https://formatter.nextwell.top/api/v1/limits
Il servizio esterno di minificazione consente 30 richieste al minuto per l’intero sito, non per visitatore. Un token bucket condiviso ne tiene il conto: quando è vuoto, la minificazione di CSS e JS viene servita dal motore locale invece di attendere o fallire. Sotto carico puoi vedere il campo engine cambiare — l’output resta valido in entrambi i casi.
Quale motore fa il lavoro
Due percorsi, un solo contratto.
Cloud — minificazione di CSS e JS
Un servizio esterno di minificazione, veloce e prudente: toglie gli spazi che si possono togliere e mantiene quelli che non si possono, così che un {calc} resti intatto. Questo servizio fa passare il codice e non aggiunge nulla di suo.
Locale — tutto il resto
Minificazione HTML, tutti e tre i formattatori e la minificazione di CSS/JS ogni volta che il budget condiviso del servizio esterno è finito o il servizio è impostato per restare offline. Costruito su {tools}, caricati solo quando una richiesta li richiede, così che un processo inattivo resti leggero.
Imposta {param} per fissare una richiesta su un solo percorso.
Che cosa viene conservato
Nulla. Il codice resta in memoria per la durata della richiesta e poi viene scartato. Non viene scritto su disco e non compare mai in un log. Quello che i log contengono davvero: un hash troncato dell’IP, il linguaggio, l’azione, il conteggio dei byte, il motore e la durata.
Domande
Serve una chiave?
No. Il servizio è aperto e il limite è invece per indirizzo IP.
Il mio codice viene inviato da qualche parte?
La minificazione di CSS e JavaScript viene inoltrata a un servizio esterno, quindi quel codice lascia questo server. La formattazione e tutto il lavoro su HTML avvengono su questo server. Imposta engine=local per tenere tutto qui.
Posso usarlo in uno script di build?
Sì, è a questo che servono gli endpoint raw. Resta entro i limiti e tieni presente che sotto carico il motore può ripiegare.
Perché il mio JavaScript minificato è rinominato?
Il minificatore a monte accorcia i nomi delle variabili locali: è sicuro ed è da lì che viene gran parte del risparmio. Formattare non riporta indietro i nomi originali — non può farlo nulla.
Qual è il file più grande che posso inviare?
2 MB in una richiesta. I file più grandi vengono rifiutati con 413 invece di essere troncati.