Formatter

API-Dokumentation

Eine POST-Anfrage formatiert eine Datei. Kein Schlüssel, kein Konto, keine Signatur — die Adresse und ein Body sind der ganze Vertrag.

Schnellstart

Ein Stylesheet minifizieren und das Ergebnis ausgeben:

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}

Tausche {css} gegen {js} oder {html} und {minify} gegen {beautify}. Jede Kombination funktioniert.

Endpunkte

Die Basisadresse ist {base}. Alles Folgende ist ein POST, sofern nicht anders angegeben.

Methode Pfad Zweck
POST/api/v1/minify/{lang}Minifizieren, JSON-Antwort
POST/api/v1/minify/{lang}/rawMinifizieren, Antwort als reiner Text
POST/api/v1/beautify/{lang}Formatieren, JSON-Antwort
POST/api/v1/beautify/{lang}/rawFormatieren, Antwort als reiner Text
GET/api/v1/limitsWas dieser IP noch bleibt, ohne eine Anfrage zu verbrauchen
GET/api/v1/healthVerfügbarkeitsprüfung, nie ratenbegrenzt

{lang} ist css, js oder html.

Den Code senden

An jedem Endpunkt werden drei Body-Formate akzeptiert — nimm das, was dein Client dir leicht macht.

Formularkodiert

Ein Feld {input}, {type}. Das ist die Form, die auch die Minifizierer von Toptal erwarten, ein bestehendes Skript ändert also nur seine Adresse.

curl --data-urlencode 'input=body{margin:0;padding:0}' \
  https://formatter.nextwell.top/api/v1/beautify/css

JSON

{type} mit einem String {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

Roher Body

Jeder andere Content-Type: der Body ist der Code. Praktisch für {example}.

curl --data-binary @style.css \
  -H 'Content-Type: text/css' \
  https://formatter.nextwell.top/api/v1/minify/css

Größe

2 MB pro Anfrage. Alles Größere kommt als 413 zurück, ohne gelesen zu werden.

Query-Parameter

Name Werte Bedeutung
engine auto upstream local Welche Engine diese Anfrage bearbeitet. {auto} — die Vorgabe — schickt die Minifizierung von CSS und JS nach oben, solange das Kontingent reicht, und fällt sonst auf die lokale Engine zurück. {upstream} verweigert, statt zurückzufallen. {local} verlässt den Server nie.
indent 2 4 tab Nur beim Formatieren: was eine Einrückungsebene ist.
curl --data-urlencode 'input=.a{color:red}' \
  'https://formatter.nextwell.top/api/v1/beautify/css?indent=tab&engine=local'

Die Antwort

Ein erfolgreicher Aufruf liefert 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}"
}
Feld Typ Bedeutung
okbooleanBei Erfolg immer true.
actionstringminify oder beautify — was angefordert wurde.
languagestringcss, js oder html.
enginestringupstream, wenn Toptal es übernommen hat, local, wenn dieser Server es getan hat.
input_bytesnumberGröße des Gesendeten, in Bytes.
output_bytesnumberGröße des Ergebnisses, in Bytes.
saved_bytesnumberDie Differenz; negativ beim Formatieren.
saved_percentnumberDieselbe Differenz als Prozentwert, eine Nachkommastelle.
duration_msnumberDauer der Verarbeitung, Millisekunden.
outputstringDer formatierte Code.

Antworten als reiner Text

Hänge {raw} an einen beliebigen Format-Endpunkt an, und der Body ist das Ergebnis und sonst nichts, als {type}. Die Header bleiben gleich. Nützlich, wenn der Aufrufer eine Shell ist:

curl -s --data-binary @app.js \
  -H 'Content-Type: text/javascript' \
  https://formatter.nextwell.top/api/v1/minify/js/raw > app.min.js

Antwort-Header

Header Bedeutung
X-Formatter-EngineWelche Engine das Ergebnis erzeugt hat.
X-Formatter-DurationVerarbeitungszeit in Millisekunden.
X-RateLimit-Remaining-Second-MonthWas dieser IP in jedem Fenster bleibt.
Retry-AfterBei einem 429: Sekunden, bis sich das engste verbrauchte Fenster wieder öffnet.
curl -s -D - -o /dev/null --data-urlencode 'input=.a{color:red}' \
  https://formatter.nextwell.top/api/v1/minify/css

Fehler

Jeder Fehler ist JSON in derselben Form, die auch die Minifizierer von Toptal verwenden — ein Client, der deren Fehler bereits behandelt, behandelt auch unsere:

{
  "errors": [
    { "status": 429, "title": "Too many requests", "detail": "…" }
  ]
}
Status Titel Wann
400Missing input Bad requestKein Body oder ein leeres Feld input.
404Not foundDiesen Pfad gibt es nicht.
405Method not allowedEin Format-Endpunkt wurde mit etwas anderem als POST aufgerufen.
413Payload too largeDer Body ist größer als 2 MB.
415Unsupported languageDie Sprache im Pfad ist nicht css, js oder html.
422Malformed inputDer Formatierer hat die Quelle abgelehnt — meist ein Syntaxfehler.
429Too many requestsEines der Ratenlimit-Fenster ist verbraucht. Lies Retry-After.
502Upstream failedNur mit engine=upstream: Toptal hat nicht geantwortet. Ohne diese Festlegung wäre die Anfrage lokal ausgewichen.
500Internal errorAlles andere.

Ratenbegrenzung

Pro IP-Adresse, fünf gleitende Fenster, alle zugleich durchgesetzt. Eine Anfrage muss in alle fünf passen.

Fenster Limit
Pro Sekunde{n} Anfragen
Pro Minute{n} Anfragen
Pro Stunde{n} Anfragen
Pro Tag{n} Anfragen
Pro Monat{n} Anfragen

Ist ein Fenster verbraucht, lautet die Antwort 429 mit einem Retry-After-Header, der die Sekunden bis zur Wiederöffnung des engsten Fensters nennt. Nichts wird in eine Warteschlange gestellt.

Die Zähler liegen in einer kleinen Datenbank auf der Platte, ein Neustart des Dienstes schenkt also niemandem einen frischen Tag.

{endpoint} meldet den aktuellen Stand aller fünf Fenster, ohne eines zu verbrauchen.

curl https://formatter.nextwell.top/api/v1/limits

Toptal erlaubt 30 Anfragen pro Minute für diesen gesamten Dienst, nicht pro Besucher. Ein gemeinsamer Token-Bucket führt darüber Buch: Ist er leer, übernimmt die lokale Engine die Minifizierung von CSS und JS, statt zu warten oder zu scheitern. Unter Last kann sich das Feld engine also ändern — die Ausgabe bleibt in beiden Fällen gültig.

Welche Engine die Arbeit macht

Zwei Wege, ein Vertrag.

Toptal — Minifizierung von CSS und JS

Ihre Minifizierer sind schnell und zurückhaltend: Sie entfernen den Whitespace, der weg kann, und behalten den, der bleiben muss, sodass etwa {calc} unversehrt bleibt. Dieser Dienst reicht den Code durch und fügt nichts Eigenes hinzu.

Lokal — alles andere

HTML-Minifizierung, alle drei Formatierer und die Minifizierung von CSS/JS, sobald das gemeinsame Upstream-Kontingent aufgebraucht ist oder der Dienst auf offline gestellt ist. Gebaut auf {tools}, geladen erst dann, wenn eine Anfrage sie braucht, damit ein untätiger Prozess klein bleibt.

Setze {param}, um eine Anfrage auf einen Weg festzulegen.

Was gespeichert wird

Nichts. Der Code liegt für die Dauer der Anfrage im Speicher und wird danach verworfen. Er wird nicht auf die Platte geschrieben und taucht nie in einem Log auf. Was die Logs sehr wohl enthalten: einen gekürzten Hash der IP, die Sprache, die Aktion, die Byte-Anzahl, die Engine und die Dauer.

Fragen

Brauche ich einen Schlüssel?

Nein. Der Dienst ist offen und wird stattdessen pro IP-Adresse begrenzt.

Wird mein Code irgendwohin geschickt?

Die Minifizierung von CSS und JavaScript wird an die Minifizierer von Toptal weitergereicht, dieser Code erreicht also deren Server. Das Formatieren und die gesamte HTML-Arbeit erledigt dieser Server. Setze engine=local, um alles hier zu behalten.

Kann ich es in einem Build-Skript verwenden?

Ja, dafür sind die raw-Endpunkte da. Bleib innerhalb der Limits und bedenke, dass die Engine unter Last zurückfallen kann.

Warum ist mein minifiziertes JavaScript umbenannt?

Der Upstream-Minifizierer kürzt lokale Variablennamen, was sicher ist und den größten Teil der Ersparnis ausmacht. Formatieren holt die ursprünglichen Namen nicht zurück — das kann nichts.

Wie groß darf die Datei höchstens sein?

2 MB in einer Anfrage. Größere Dateien werden mit 413 abgelehnt, statt gekürzt zu werden.