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 и даже не читается.

Параметры запроса

Имя Значения Описание
indent 2 4 tab Только для форматирования: чем является один уровень отступа.
curl
curl --data-urlencode 'input=.a{color:red}' \
  'https://formatter.nextwell.top/api/v1/beautify/css?indent=tab'

Ответ

Успешный вызов возвращает JSON:

JSON
{
  "ok": true,
  "action": "minify",
  "language": "css",
  "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.
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-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 одного и того же вида:

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.
500Internal errorВсё остальное.

Лимиты запросов

На IP-адрес, пять скользящих окон, все действуют одновременно. Запрос должен уложиться во все пять.

Окно Лимит
В секундуЗапросов: {n}
В минутуЗапросов: {n}
В часЗапросов: {n}
В суткиЗапросов: {n}
В месяцЗапросов: {n}

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

Счётчики лежат в небольшой базе на диске, так что перезапуск сервиса никому не выдаёт новые сутки.

{endpoint} показывает текущее состояние всех пяти окон, не тратя запрос.

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

Что сохраняется

Ничего. Код отправляется на наш сервер, живёт в памяти ровно столько, сколько длится запрос, и удаляется. На диск он не пишется и в логах не появляется. В логи попадают только: укороченный хеш IP, язык, действие, число байт и длительность.

Вопросы

Нужен ли ключ?

Нет. Сервис открыт, вместо ключа действует ограничение по IP-адресу.

Отправляется ли мой код куда-либо?

Только на наш собственный сервер. Вся обработка идёт там, в памяти, код не сохраняется и не попадает в логи.

Можно ли использовать это в сборочном скрипте?

Да, для этого и сделаны эндпоинты /raw. Держитесь в пределах лимитов.

Почему в минифицированном JavaScript изменились имена?

Минификатор укорачивает имена локальных переменных — это безопасно и даёт основную часть экономии. Форматирование не вернёт исходные имена: их не вернёт уже ничто.

Файл какого размера можно отправить?

2 МБ за один запрос. Файлы больше отклоняются с 413, а не обрезаются.