/api/v1
Документація API
Один POST-запит форматує файл. Ні ключа, ні облікового запису, ні підпису — увесь контракт це адреса й тіло запиту.
Швидкий старт
Мініфікувати таблицю стилів і вивести результат:
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}
Замініть {css} на {js} або {html}, а {minify} на {beautify} — працює будь-яка комбінація.
Ендпоїнти
Базова адреса — {base}. Усе нижче — POST, якщо не сказано інше.
| Метод | Шлях | Призначення |
|---|---|---|
| POST | /api/v1/minify/{lang} | Мініфікація, відповідь JSON |
| POST | /api/v1/minify/{lang}/raw | Мініфікація, відповідь звичайним текстом |
| POST | /api/v1/beautify/{lang} | Форматування, відповідь JSON |
| POST | /api/v1/beautify/{lang}/raw | Форматування, відповідь звичайним текстом |
| GET | /api/v1/limits | Залишок лімітів цієї IP-адреси, без витрати запиту |
| GET | /api/v1/health | Перевірка живучості, ніколи не обмежується |
{lang} — це css, js або html.
Як надіслати код
Кожен ендпоїнт приймає тіло у трьох виглядах — обирайте той, який простіше сформувати вашому клієнту.
Форма urlencoded
Поле {input}, {type}. Такий вигляд тіла запиту усталений у подібних API мініфікації, тож готовому скрипту достатньо змінити адресу.
curl --data-urlencode 'input=body{margin:0;padding:0}' \
https://formatter.nextwell.top/api/v1/beautify/css
JSON
{type} з рядком у полі {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
Сире тіло
Будь-який інший content type: тілом іде сам код. Зручно для {example}.
curl --data-binary @style.css \
-H 'Content-Type: text/css' \
https://formatter.nextwell.top/api/v1/minify/css
Розмір
2 МБ на запит. Усе, що більше, повертається як 413 і навіть не читається.
Параметри запиту
| Ім’я | Значення | Опис |
|---|---|---|
engine |
auto upstream local |
Який рушій обробить запит. {auto} — значення за замовчуванням — надсилає мініфікацію CSS і JS до зовнішнього сервісу, доки вистачає спільного ліміту, а потім перемикається на локальний рушій. {upstream} не перемикається, а повертає помилку. {local} не виходить за межі сервера. |
indent |
2 4 tab |
Лише для форматування: чим є один рівень відступу. |
curl --data-urlencode 'input=.a{color:red}' \
'https://formatter.nextwell.top/api/v1/beautify/css?indent=tab&engine=local'
Відповідь
Успішний виклик повертає 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}"
}
| Поле | Тип | Опис |
|---|---|---|
ok | boolean | За успіху завжди true. |
action | string | minify або beautify — що було запитано. |
language | string | css, js або html. |
engine | string | upstream, якщо обробив зовнішній сервіс, local — якщо цей сервер. |
input_bytes | number | Розмір надісланого, у байтах. |
output_bytes | number | Розмір результату, у байтах. |
saved_bytes | number | Різниця; під час форматування від’ємна. |
saved_percent | number | Та сама різниця у відсотках, з одним знаком після коми. |
duration_ms | number | Скільки тривала обробка, у мілісекундах. |
output | string | Оброблений код. |
Відповіді звичайним текстом
Допишіть {raw} до будь-якого ендпоїнта форматування — і тілом відповіді буде лише результат, з типом {type}. Заголовки ті самі. Зручно, коли запит іде з шелла:
curl -s --data-binary @app.js \
-H 'Content-Type: text/javascript' \
https://formatter.nextwell.top/api/v1/minify/js/raw > app.min.js
Заголовки відповіді
| Заголовок | Опис |
|---|---|
X-Formatter-Engine | Який рушій видав результат. |
X-Formatter-Duration | Час обробки в мілісекундах. |
X-RateLimit-Remaining-Second … -Month | Скільки лишилося в кожному вікні для цієї IP-адреси. |
Retry-After | При 429: секунди до відкриття найвужчого вичерпаного вікна. |
curl -s -D - -o /dev/null --data-urlencode 'input=.a{color:red}' \
https://formatter.nextwell.top/api/v1/minify/css
Помилки
Будь-яка помилка — це JSON того вигляду, який усталений для подібних API: клієнт, що вже розбирає такий формат, розбере й наші помилки:
{
"errors": [
{ "status": 429, "title": "Too many requests", "detail": "…" }
]
}
| Код | Поле title | Коли |
|---|---|---|
| 400 | Missing input Bad request | Немає тіла або поле input порожнє. |
| 404 | Not found | Такого шляху немає. |
| 405 | Method not allowed | До ендпоїнта форматування звернулися не через POST. |
| 413 | Payload too large | Тіло більше за 2 МБ. |
| 415 | Unsupported language | Мова у шляху не css, не js і не html. |
| 422 | Malformed input | Форматувальник відмовився обробляти джерело — зазвичай це синтаксична помилка. |
| 429 | Too many requests | Одне з вікон ліміту вичерпано. Дивіться Retry-After. |
| 502 | Upstream failed | Лише за engine=upstream: зовнішній сервіс не відповів. Без цього перевизначення запит пішов би на локальний рушій. |
| 500 | Internal error | Усе інше. |
Ліміти запитів
На IP-адресу, п’ять ковзних вікон, усі діють одночасно. Запит має вміститися в усі п’ять.
| Вікно | Ліміт |
|---|---|
| За секунду | Запитів: {n} |
| За хвилину | Запитів: {n} |
| За годину | Запитів: {n} |
| За добу | Запитів: {n} |
| За місяць | Запитів: {n} |
Коли вікно вичерпано, приходить 429 із заголовком Retry-After: у ньому секунди до відкриття найвужчого вікна. Нічого не ставиться в чергу.
Лічильники лежать у невеликій базі на диску, тож перезапуск сервісу нікому не видає нову добу.
{endpoint} показує поточний стан усіх п’яти вікон, не витрачаючи запиту.
curl https://formatter.nextwell.top/api/v1/limits
Зовнішній сервіс мініфікації дозволяє 30 запитів на хвилину на весь сайт, а не на кожного відвідувача. За цим стежить спільний лічильник-бакет: коли він порожній, мініфікацію CSS і JS виконує локальний рушій — замість очікування чи помилки. Під навантаженням поле engine може змінюватися, але результат в обох випадках коректний.
Який рушій виконує роботу
Два шляхи, один контракт.
Хмара — мініфікація CSS і JS
Зовнішній сервіс мініфікації, швидкий і обережний: прибирає ті пробіли, які можна прибрати, і зберігає ті, які не можна, тож конструкції на кшталт {calc} лишаються цілими. Цей сервіс пропускає код крізь нього і нічого не додає від себе.
Локальний рушій — усе інше
Мініфікація HTML, усі три форматувальники та мініфікація CSS/JS, коли спільний ліміт зовнішнього сервісу вичерпано або сервісу задано працювати без зовнішніх викликів. Побудований на {tools}, які підвантажуються лише тоді, коли їх потребує запит, — процес у простої лишається невеликим.
Задайте {param}, щоб закріпити запит за одним шляхом.
Що зберігається
Нічого. Код живе в пам’яті рівно стільки, скільки триває запит, і зникає. На диск він не пишеться і в логах не з’являється. У логи потрапляють лише: скорочений хеш IP, мова, дія, кількість байтів, рушій і тривалість.
Питання
Чи потрібен ключ?
Ні. Сервіс відкритий, замість ключа діє обмеження за IP-адресою.
Чи надсилається мій код кудись?
Мініфікація CSS і JavaScript проксіюється до зовнішнього сервісу мініфікації, тож цей код залишає цей сервер. Форматування та вся робота з HTML ідуть тут. Задайте engine=local, щоб усе лишалося на цьому сервері.
Чи можна використовувати це у скрипті збірки?
Так, саме для цього зроблено ендпоїнти /raw. Тримайтеся в межах лімітів і зважайте, що під навантаженням рушій може перемкнутися на локальний.
Чому в мініфікованому JavaScript змінилися імена?
Зовнішній мініфікатор скорочує імена локальних змінних — це безпечно й дає більшу частину економії. Форматування не поверне початкові імена: їх не поверне вже ніщо.
Файл якого розміру можна надіслати?
2 МБ за один запит. Більші файли відхиляються з 413, а не обрізаються.