コンテンツへスキップ
Tutorial

REST API 経由で cron 式を解析および検証する

| 4 min read

Botoi cron パーサー API を使用して、cron 式を検証し、人間が読める説明を生成し、今後の実行をプレビューします。 管理パネル用の cron プレビュー ウィジェットを数分で構築します。

Clock gears and scheduling calendar
Photo by Lukas Blazek on Unsplash

ユーザーが定期的なジョブをスケジュールする管理パネルを構築しています。 cron 式を入力します テキストフィールドに入力して保存を押すと、システムが正しい処理を行うことを期待します。 問題: cron 構文 不可解です。 */15 * * * * それは十分明らかですが、どうですか 0 9 1-15 * 1-5? ほとんどのユーザー (そして多くの開発者) は、一目でそれを読み取ることができません。

式を保存する「前」に、ユーザーに式の意味を示す必要があります。 のような説明 「月曜から金曜の 1 日から 15 日の 09:00」は、ツールチップのリンク以上の価値があります。 crontab.guruへ。

Botoi の cron パーサー API は、単一の POST リクエストで 3 つのことを実行します。式を検証します。 人間が判読できる説明を生成し、次にスケジュールされた実行時間を返します。 クロンなし ライブラリをインストールするだけで、解析ロジックを維持する必要はありません。

解析エンドポイント

cron 式を送信する /v1/cron/parse そして構造的な内訳を取り戻します。

curl -X POST https://api.botoi.com/v1/cron/parse \\
  -H "Content-Type: application/json" \\
  -d '{"expression": "*/15 * * * *"}'

応答:

{
  "success": true,
  "data": {
    "isValid": true,
    "description": "Every 15 minutes",
    "nextRuns": [
      "2026-03-26T18:30:00Z",
      "2026-03-26T18:45:00Z",
      "2026-03-26T19:00:00Z",
      "2026-03-26T19:15:00Z",
      "2026-03-26T19:30:00Z"
    ],
    "parts": {
      "minute": "*/15",
      "hour": "*",
      "dayOfMonth": "*",
      "month": "*",
      "dayOfWeek": "*"
    }
  }
}

応答には必要なものがすべて含まれています。 isValid 旗、平易な英語 description、UTC での次の 5 つの実行時間、および個々の parts 分野ごとに分けてあります。 説明を UI に直接表示し、 nextRuns 今後の実行のプレビューを表示する配列。

今後のランをさらに取得する

5 つ以上のプレビュー日が必要な場合、またはスケジュールのみを気にし、 説明を使用するには、 /v1/cron/next 終点。 渡す count パラメータ 今後何回の実行時間を返すかを制御します。

curl -X POST https://api.botoi.com/v1/cron/next \\
  -H "Content-Type: application/json" \\
  -d '{"expression": "0 9 * * MON-FRI", "count": 5}'

応答:

{
  "success": true,
  "data": {
    "nextRuns": [
      "2026-03-27T09:00:00Z",
      "2026-03-30T09:00:00Z",
      "2026-03-31T09:00:00Z",
      "2026-04-01T09:00:00Z",
      "2026-04-02T09:00:00Z"
    ]
  }
}

3 月 27 日(金曜日)と 3 月 30 日(月曜日)の間のギャップに注目してください。 表現 0 9 * * MON-FRI 週末をスキップすると、API はそれを正しく反映します。

cron プレビュー ウィジェットを構築する

解析エンドポイントをフロントエンド入力フィールドに接続する方法は次のとおりです。 ユーザーが cron を入力すると 式を実行すると、ウィジェットが API を呼び出し、説明と今後の実行をリアルタイムで表示します。

async function parseCron(expression) {
  const res = await fetch("https://api.botoi.com/v1/cron/parse", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ expression }),
  });
  return res.json();
}

// Example: user types "0 9 * * MON-FRI" into a text input
const input = document.querySelector("#cron-input");
const preview = document.querySelector("#cron-preview");

input.addEventListener("input", async (e) => {
  const { data } = await parseCron(e.target.value);

  if (data.isValid) {
    preview.innerHTML = \`
      <p class="text-green-600">\\\${data.description}</p>
      <ul>
        \\\${data.nextRuns
          .map((run) => \`<li>\\\${new Date(run).toLocaleString()}</li>\`)
          .join("")}
      </ul>
    \

運用環境で使用する場合は、キーストロークごとにリクエストが起動されないように、デバウンス (200 ~ 300 ミリ秒) を追加します。 API は Cloudflare のエッジから 50 ミリ秒未満で応答するため、プレビューはすぐに表示されます。 リクエストが出ます。

React / Preact バージョン

React または Preact を使用している場合は、同じロジックをラップするコンポーネントを次に示します。 AbortController 古いリクエストをキャンセルします。

import { useState, useEffect } from "react";

function CronPreview({ value }) {
  const [result, setResult] = useState(null);

  useEffect(() => {
    if (!value.trim()) {
      setResult(null);
      return;
    }

    const controller = new AbortController();
    fetch("https://api.botoi.com/v1/cron/parse", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ expression: value }),
      signal: controller.signal,
    })
      .then((r) => r.json())
      .then(({ data }) => setResult(data))
      .catch(() => {});

    return () => controller.abort();
  }, [value]);

  if (!result) return null;

  if (!result.isValid) {
    return <p className="text-red-600">Invalid expression</p>;
  }

  return (
    <div>
      <p className="font-medium">{result.description}</p>
      <p className="text-sm text-gray-500 mt-1">
        Next run: {new Date(result.nextRuns[0]).toLocaleString()}
      </p>
    </div>
  );
}

保存する前にユーザー入力を検証する

クライアント側のプレビューは UX に優れていますが、事前にサーバーでも検証する必要があります。 cron ジョブを永続化します。 バックエンドから解析エンドポイントを呼び出して、 isValid フラグ。

async function saveCronJob(name, expression) {
  // Validate the expression before saving
  const res = await fetch("https://api.botoi.com/v1/cron/parse", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ expression }),
  });
  const { data } = await res.json();

  if (!data.isValid) {
    throw new Error("Invalid cron expression: " + expression);
  }

  // Save to your database with the parsed metadata
  await db.cronJobs.create({
    name,
    expression,
    description: data.description,
    nextRun: data.nextRuns[0],
  });

  return { description: data.description, nextRun: data.nextRuns[0] };
}

ユーザーが無効な式を送信すると、API は適切な応答を返します。

{
  "success": true,
  "data": {
    "isValid": false,
    "description": null,
    "nextRuns": [],
    "parts": null
  }
}

キャッチする例外も、書き込む正規表現もありません。 チェック data.isValid そしてエラーを返します ユーザーへのメッセージ。 を保管することもできます。 description そして nextRun データベース内の生の式と一緒に、それらをリストビューに表示できます。 APIを再度呼び出します。

一般的な cron 式と API が返すもの

表現 説明
* * * * * 毎分
*/15 * * * * 15分ごと
0 * * * * 1時間ごと
0 9 * * MON-FRI 月曜から金曜の09:00
0 0 1 * * 毎月1日午前0時
30 4 * * SUN 日曜日の04:30に
0 9,17 * * * 毎日09:00と17:00
0 0 * * 0 日曜日の真夜中に

これらの各式は、同じ構造化された応答 (有効性フラグ、説明、 次に実行され、解析された部分。 API を統合するときに、上の表をテスト ケースとして使用できます。

cron 解析を API にオフロードする理由は何ですか?

  • ライブラリ依存性はありません。 Cron 解析ライブラリはすべての言語に存在しますが、 バンドル サイズ (フロントエンド) または依存関係のメンテナンス (バックエンド) が追加されます。 単一の HTTP 呼び出しで置き換えられます。 図書館。
  • サービス間で一貫した動作。 システムに Node.js スケジューラがある場合は、 Python ワーカーと Go マイクロサービスは、すべて異なる方法で cron 式を解析します。 1 つの API 唯一の真実の情報源を提供します。
  • 人間が読める説明を無料で提供します。 cronから自然言語を生成する 構文はスケジュールを解析するよりも困難です。 API は 1 回の呼び出しで両方を処理します。
  • ユーザー向けのインスタント プレビュー。 50ms 未満のエッジ応答によりリアルタイム検証が可能 デバウンスを伴うすべてのキーストロークでも実用的です。

FAQ

cron パーサー API は、@daily や @weekly などの非標準の表現をサポートしていますか?
はい。 解析エンドポイントは、標準の 5 フィールド cron 式と、@yearly、@monthly、@weekly、@daily、@hourly などの一般的な短縮エイリアスの両方を受け入れます。 応答は、それらを標準の 5 フィールド形式に正規化します。
nextRuns のタイムスタンプはどのタイムゾーンですか?
応答内のすべてのタイムスタンプは UTC (ISO 8601 形式) です。 Intl.DateTimeFormat または date-fns などのライブラリを使用して、クライアント側でユーザーのローカル タイムゾーンに変換します。
次回リクエストできる実行回数に制限はありますか?
/v1/cron/next エンドポイントは count パラメータを受け入れます。 1 回の呼び出しで最大 100 件の今後の実行時間をリクエストできます。 パラメータを省略した場合のデフォルトは 5 です。
cron パーサーを使用するには API キーが必要ですか?
いいえ。匿名アクセスは、IP ベースのレート制限により、1 分あたり 5 リクエストで利用できます。 スループットを高めるには、botoi.com/api で API キーにサインアップしてください。
cron 式で MON-FRI のような曜日名を使用できますか?
はい。 パーサーは、適切なフィールドで 3 文字の日の略称 (SUN、MON、TUE、WED、THU、FRI、SAT) と月の略称 (JAN から 12 月) をサポートします。

botoiで開発を始めよう

150以上のAPIエンドポイント。検索、テキスト処理、画像生成、開発者ユーティリティに対応。無料プラン、クレジットカード不要。