Formatter
/api/v1

API ドキュメント

POST リクエスト 1 回でファイルを処理します。キーもアカウントも署名も不要で、アドレスとボディが取り決めのすべてです。

クイックスタート

スタイルシートを圧縮して結果を出力します。

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 のいずれかです。

コードの送り方

どのエンドポイントも 3 種類のボディ形式を受け付けます。クライアントで扱いやすいものを選んでください。

フォームエンコード

{input} フィールドを {type} で送ります。これは圧縮系の API が慣例的に受け取る形式なので、既存のスクリプトはアドレスを変えるだけで済みます。

curl
curl --data-urlencode 'input=body{margin:0;padding:0}' \
  https://formatter.nextwell.top/api/v1/beautify/css

JSON

{input} 文字列を含む {type} です。

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

生のボディ

それ以外のコンテンツタイプでは、ボディがそのままコードになります。{example} のような使い方に便利です。

curl
curl --data-binary @style.css \
  -H 'Content-Type: text/css' \
  https://formatter.nextwell.top/api/v1/minify/css

サイズ

1 リクエストあたり 2 MB です。これを超えるものは読まれずに 413 が返ります。

クエリパラメータ

名前 値 意味
indent 2 4 tab 整形時のみ有効で、インデント 1 段分の中身を指定します。
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同じ差分を百分率で表したもので、小数第 1 位までです。
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-After429 のとき、使い切ったウィンドウのうち最も厳しいものが空くまでの秒数です。
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": "…" }
  ]
}
ステータス タイトル 発生条件
400Missing input Bad requestボディがない、または input フィールドが空です。
404Not foundそのパスはありません。
405Method not allowed処理用のエンドポイントを POST 以外で呼び出しました。
413Payload too largeボディが 2 MB を超えています。
415Unsupported languageパスの言語が css、js、html のいずれでもありません。
422Malformed inputフォーマッタがソースを受け付けませんでした(多くは構文エラー)、または処理に時間がかかりすぎました。
429Too many requestsレート制限のウィンドウのいずれかを使い切りました。Retry-After を見てください。
500Internal errorそれ以外のすべてです。

レート制限

IP アドレスごとに 5 つのローリングウィンドウがあり、すべて同時に効きます。リクエストは 5 つすべてに収まる必要があります。

ウィンドウ 上限
1 秒あたり{n} 回
1 分あたり{n} 回
1 時間あたり{n} 回
1 日あたり{n} 回
1 か月あたり{n} 回

ウィンドウを使い切ると 429 が返り、Retry-After ヘッダーに最も厳しいウィンドウが空くまでの秒数が入ります。キューには入りません。

カウンターはディスク上の小さなデータベースに置かれているので、サービスを再起動しても 1 日分の枠が戻ることはありません。

{endpoint} は 5 つのウィンドウの現在の状態を返しますが、枠は消費しません。

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

保存されるもの

何も残しません。コードは私たちのサーバーに送られ、リクエストの間だけメモリに置かれて破棄されます。ディスクには書かれず、ログにも現れません。ログに残るのは、IP を短縮したハッシュ、言語、操作、バイト数、所要時間だけです。

よくある質問

キーは必要ですか。

不要です。サービスは公開されていて、代わりに IP アドレスで制限しています。

コードはどこかに送られますか。

私たち自身のサーバーにだけ送られます。処理はすべてそこでメモリ上で行われ、コードが保存されることも、ログに書かれることもありません。

ビルドスクリプトで使えますか。

使えます。raw のエンドポイントはそのためにあります。制限の範囲内でお使いください。

圧縮した JavaScript の名前が変わるのはなぜですか。

圧縮器はローカル変数の名前を短くします。これは安全な処理で、削減量の大半はここから来ています。整形しても元の名前は戻りません。どんな方法でも戻せません。

送れるファイルの最大サイズはどれくらいですか。

1 リクエストにつき 2 MB です。それより大きいファイルは切り詰められず、413 で拒否されます。