Formatter

Документация 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}. Такой же вид принимают минификаторы Toptal, так что готовому скрипту достаточно поменять адрес.

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

Ответы обычным текстом

Допишите {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 того же вида, что у минификаторов Toptal: клиент, который уже разбирает их ошибки, разберёт и наши:

{
  "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: Toptal не ответил. Без этого переопределения запрос ушёл бы на локальный движок.
500Internal errorВсё остальное.

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

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

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

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

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

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

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

Toptal разрешает 30 запросов в минуту на весь сервис, а не на каждого посетителя. За этим следит общий счётчик-бакет: когда он пуст, минификацию CSS и JS выполняет локальный движок — вместо ожидания или ошибки. Под нагрузкой поле engine может меняться, но результат в обоих случаях корректен.

Какой движок делает работу

Два пути, один контракт.

Toptal — минификация CSS и JS

Их минификаторы быстрые и осторожные: убирают те пробелы, которые можно убрать, и сохраняют те, которые нельзя, так что конструкции вроде {calc} остаются целыми. Этот сервис пропускает код через них и ничего не добавляет от себя.

Локальный движок — всё остальное

Минификация HTML, все три форматировщика и минификация CSS/JS, когда общий лимит внешнего сервиса исчерпан или сервису задано работать без внешних вызовов. Построен на {tools}, которые подгружаются только тогда, когда их требует запрос, — простаивающий процесс остаётся маленьким.

Задайте {param}, чтобы закрепить запрос за одним путём.

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

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

Вопросы

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

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

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

Минификация CSS и JavaScript проксируется в минификаторы Toptal, так что этот код попадает на их серверы. Форматирование и вся работа с HTML идут на этом сервере. Задайте engine=local, чтобы всё оставалось здесь.

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

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

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

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

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

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