/api/v1
Dokumentacja API
Jedno żądanie POST formatuje plik. Bez klucza, bez konta, bez podpisu — cały kontrakt to adres i treść żądania.
Szybki start
Zminifikuj arkusz stylów i wypisz wynik:
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}
Zamień {css} na {js} albo {html}, a {minify} na {beautify} — działa każda kombinacja.
Endpointy
Adres bazowy to {base}. Wszystko poniżej to POST, o ile nie napisano inaczej.
| Metoda | Ścieżka | Przeznaczenie |
|---|---|---|
| POST | /api/v1/minify/{lang} | Minifikacja, odpowiedź JSON |
| POST | /api/v1/minify/{lang}/raw | Minifikacja, odpowiedź zwykłym tekstem |
| POST | /api/v1/beautify/{lang} | Formatowanie, odpowiedź JSON |
| POST | /api/v1/beautify/{lang}/raw | Formatowanie, odpowiedź zwykłym tekstem |
| GET | /api/v1/limits | Ile zostało temu adresowi IP, bez zużywania żądania |
| GET | /api/v1/health | Sprawdzenie działania, nigdy nie limitowane |
{lang} to css, js albo html.
Wysyłanie kodu
Każdy endpoint przyjmuje treść w trzech postaciach — wybierz tę, którą łatwiej złożyć twojemu klientowi.
Formularz urlencoded
Pole {input}, {type}. Taką postać przyjmują zwyczajowo API minifikacji, więc istniejący skrypt zmienia tylko adres.
curl --data-urlencode 'input=body{margin:0;padding:0}' \
https://formatter.nextwell.top/api/v1/beautify/css
JSON
{type} z łańcuchem znaków w polu {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
Surowa treść
Dowolny inny content type: treścią jest sam kod. Wygodne przy {example}.
curl --data-binary @style.css \
-H 'Content-Type: text/css' \
https://formatter.nextwell.top/api/v1/minify/css
Rozmiar
2 MB na żądanie. Wszystko większe wraca jako 413 i nie jest nawet czytane.
Parametry zapytania
| Nazwa | Wartości | Opis |
|---|---|---|
engine |
auto upstream local |
Który silnik obsłuży to żądanie. {auto} — wartość domyślna — wysyła minifikację CSS i JS do serwisu zewnętrznego, dopóki starcza wspólnego budżetu, a potem przechodzi na silnik lokalny. {upstream} nie przechodzi, tylko zwraca błąd. {local} nigdy nie opuszcza serwera. |
indent |
2 4 tab |
Tylko przy formatowaniu: czym jest jeden poziom wcięcia. |
curl --data-urlencode 'input=.a{color:red}' \
'https://formatter.nextwell.top/api/v1/beautify/css?indent=tab&engine=local'
Odpowiedź
Udane wywołanie zwraca 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}"
}
| Pole | Typ | Opis |
|---|---|---|
ok | boolean | Przy powodzeniu zawsze true. |
action | string | minify albo beautify — o co poproszono. |
language | string | css, js albo html. |
engine | string | upstream, jeśli obsłużyła to usługa zewnętrzna, local — jeśli ten serwer. |
input_bytes | number | Rozmiar tego, co wysłano, w bajtach. |
output_bytes | number | Rozmiar wyniku, w bajtach. |
saved_bytes | number | Różnica; przy formatowaniu ujemna. |
saved_percent | number | Ta sama różnica w procentach, z jednym miejscem po przecinku. |
duration_ms | number | Ile trwała praca, w milisekundach. |
output | string | Przetworzony kod. |
Odpowiedzi zwykłym tekstem
Dopisz {raw} do dowolnego endpointu formatowania, a treścią odpowiedzi będzie wyłącznie wynik, jako {type}. Nagłówki są te same. Przydatne, gdy wywołanie idzie z powłoki:
curl -s --data-binary @app.js \
-H 'Content-Type: text/javascript' \
https://formatter.nextwell.top/api/v1/minify/js/raw > app.min.js
Nagłówki odpowiedzi
| Nagłówek | Opis |
|---|---|
X-Formatter-Engine | Który silnik wytworzył wynik. |
X-Formatter-Duration | Czas przetwarzania w milisekundach. |
X-RateLimit-Remaining-Second … -Month | Ile zostało w każdym oknie dla tego adresu IP. |
Retry-After | Przy 429: sekundy do otwarcia najciaśniejszego wyczerpanego okna. |
curl -s -D - -o /dev/null --data-urlencode 'input=.a{color:red}' \
https://formatter.nextwell.top/api/v1/minify/css
Błędy
Każdy błąd to JSON w postaci przyjętej dla tego rodzaju API, więc klient, który obsługuje już taką postać, obsłuży i nasze błędy:
{
"errors": [
{ "status": 429, "title": "Too many requests", "detail": "…" }
]
}
| Kod | Pole title | Kiedy |
|---|---|---|
| 400 | Missing input Bad request | Brak treści albo puste pole input. |
| 404 | Not found | Nie ma takiej ścieżki. |
| 405 | Method not allowed | Do endpointu formatowania trafiło coś innego niż POST. |
| 413 | Payload too large | Treść przekracza 2 MB. |
| 415 | Unsupported language | Język w ścieżce to nie css, js ani html. |
| 422 | Malformed input | Narzędzie formatujące odrzuciło źródło — zwykle to błąd składni. |
| 429 | Too many requests | Jedno z okien limitu jest wyczerpane. Sprawdź Retry-After. |
| 502 | Upstream failed | Tylko przy engine=upstream: usługa zewnętrzna nie odpowiedziała. Bez tego wymuszenia żądanie trafiłoby do silnika lokalnego. |
| 500 | Internal error | Wszystko inne. |
Limity żądań
Na adres IP, pięć okien przesuwnych, wszystkie egzekwowane naraz. Żądanie musi zmieścić się we wszystkich pięciu.
| Okno | Limit |
|---|---|
| Na sekundę | Żądań: {n} |
| Na minutę | Żądań: {n} |
| Na godzinę | Żądań: {n} |
| Na dobę | Żądań: {n} |
| Na miesiąc | Żądań: {n} |
Gdy okno jest wyczerpane, wraca 429 z nagłówkiem Retry-After podającym sekundy do otwarcia najciaśniejszego z nich. Nic nie jest kolejkowane.
Liczniki leżą w małej bazie na dysku, więc restart usługi nikomu nie daje nowej doby.
{endpoint} pokazuje bieżący stan wszystkich pięciu okien, nie zużywając żadnego z nich.
curl https://formatter.nextwell.top/api/v1/limits
Zewnętrzna usługa minifikacji pozwala na 30 żądań na minutę dla całej witryny, a nie dla pojedynczego odwiedzającego. Pilnuje tego wspólny kubełek: gdy jest pusty, minifikację CSS i JS wykonuje silnik lokalny, zamiast czekać albo zwracać błąd. Pod obciążeniem pole engine może się zmieniać — wynik w obu przypadkach pozostaje poprawny.
Który silnik wykonuje pracę
Dwie drogi, jeden kontrakt.
W chmurze — minifikacja CSS i JS
Zewnętrzna usługa minifikacji, szybka i ostrożna: usuwa te białe znaki, które można usunąć, i zachowuje te, których nie można, więc konstrukcje w rodzaju {calc} pozostają nienaruszone. Ta usługa tylko przepuszcza przez nią kod i nie dodaje nic od siebie.
Lokalny — cała reszta
Minifikacja HTML, wszystkie trzy formatery oraz minifikacja CSS/JS, gdy wspólny budżet usługi zewnętrznej się skończy albo usługa ma działać bez wywołań na zewnątrz. Zbudowany na {tools}, ładowanych dopiero wtedy, gdy potrzebuje ich żądanie — bezczynny proces pozostaje mały.
Ustaw {param}, aby przypiąć żądanie do jednej z dróg.
Co jest przechowywane
Nic. Kod trzymany jest w pamięci przez czas trwania żądania i znika. Nie jest zapisywany na dysk i nigdy nie pojawia się w logach. Co logi rzeczywiście niosą: skrócony hash adresu IP, język, akcję, liczbę bajtów, silnik i czas trwania.
Pytania
Czy potrzebuję klucza?
Nie. Usługa jest otwarta, a limity liczone są po adresie IP.
Czy mój kod jest gdzieś wysyłany?
Minifikacja CSS i JavaScript jest proxowana do zewnętrznej usługi minifikacji, więc ten kod opuszcza ten serwer. Formatowanie i cała praca z HTML odbywa się tutaj. Ustaw engine=local, aby wszystko zostało na tym serwerze.
Czy mogę użyć tego w skrypcie budowania?
Tak, po to są endpointy /raw. Trzymaj się limitów i pamiętaj, że pod obciążeniem silnik może przejść na lokalny.
Dlaczego w zminifikowanym kodzie JavaScript zmieniły się nazwy?
Zewnętrzny minifikator skraca nazwy zmiennych lokalnych — to bezpieczne i stąd bierze się większość oszczędności. Formatowanie nie przywróci oryginalnych nazw: nie przywróci ich już nic.
Jaki największy plik mogę wysłać?
2 MB w jednym żądaniu. Większe pliki są odrzucane z 413, a nie obcinane.