Formatter
/api/v1

Документація API

Один POST-запит форматує файл. Ні ключа, ні облікового запису, ні підпису — увесь контракт це адреса й тіло запиту.

Швидкий старт

Мініфікувати таблицю стилів і вивести результат:

curl
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
curl --data-urlencode 'input=body{margin:0;padding:0}' \
  https://formatter.nextwell.top/api/v1/beautify/css

JSON

{type} з рядком у полі {input}.

curl
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
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
curl --data-urlencode 'input=.a{color:red}' \
  'https://formatter.nextwell.top/api/v1/beautify/css?indent=tab&engine=local'

Відповідь

Успішний виклик повертає JSON:

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}"
}
Поле Тип Опис
okbooleanЗа успіху завжди true.
actionstringminify або beautify — що було запитано.
languagestringcss, js або html.
enginestringupstream, якщо обробив зовнішній сервіс, local — якщо цей сервер.
input_bytesnumberРозмір надісланого, у байтах.
output_bytesnumberРозмір результату, у байтах.
saved_bytesnumberРізниця; під час форматування від’ємна.
saved_percentnumberТа сама різниця у відсотках, з одним знаком після коми.
duration_msnumberСкільки тривала обробка, у мілісекундах.
outputstringОброблений код.

Відповіді звичайним текстом

Допишіть {raw} до будь-якого ендпоїнта форматування — і тілом відповіді буде лише результат, з типом {type}. Заголовки ті самі. Зручно, коли запит іде з шелла:

curl
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
curl -s -D - -o /dev/null --data-urlencode 'input=.a{color:red}' \
  https://formatter.nextwell.top/api/v1/minify/css

Помилки

Будь-яка помилка — це JSON того вигляду, який усталений для подібних API: клієнт, що вже розбирає такий формат, розбере й наші помилки:

JSON
{
  "errors": [
    { "status": 429, "title": "Too many requests", "detail": "…" }
  ]
}
Код Поле title Коли
400Missing input Bad requestНемає тіла або поле input порожнє.
404Not foundТакого шляху немає.
405Method not allowedДо ендпоїнта форматування звернулися не через POST.
413Payload too largeТіло більше за 2 МБ.
415Unsupported languageМова у шляху не css, не js і не html.
422Malformed inputФорматувальник відмовився обробляти джерело — зазвичай це синтаксична помилка.
429Too many requestsОдне з вікон ліміту вичерпано. Дивіться Retry-After.
502Upstream failedЛише за engine=upstream: зовнішній сервіс не відповів. Без цього перевизначення запит пішов би на локальний рушій.
500Internal errorУсе інше.

Ліміти запитів

На IP-адресу, п’ять ковзних вікон, усі діють одночасно. Запит має вміститися в усі п’ять.

Вікно Ліміт
За секундуЗапитів: {n}
За хвилинуЗапитів: {n}
За годинуЗапитів: {n}
За добуЗапитів: {n}
За місяцьЗапитів: {n}

Коли вікно вичерпано, приходить 429 із заголовком Retry-After: у ньому секунди до відкриття найвужчого вікна. Нічого не ставиться в чергу.

Лічильники лежать у невеликій базі на диску, тож перезапуск сервісу нікому не видає нову добу.

{endpoint} показує поточний стан усіх п’яти вікон, не витрачаючи запиту.

curl
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, а не обрізаються.