Перейти к содержимому
Tutorial

Разбор и проверка выражений cron через REST API

| 4 min read

Используйте API анализатора cron Botoi для проверки выражений cron, создания удобочитаемых описаний и предварительного просмотра предстоящих запусков. Создайте виджет предварительного просмотра cron для своей панели администратора за считанные минуты.

Clock gears and scheduling calendar
Photo by Lukas Blazek on Unsplash

Вы создаете панель администратора, где пользователи планируют повторяющиеся задания. Они вводят выражение cron в текстовое поле, нажмите «Сохранить» и ожидайте, что система поступит правильно. Проблема: синтаксис cron является загадочным. */15 * * * * это достаточно ясно, но как насчет 0 9 1-15 * 1-5? Большинство пользователей (и многие разработчики) не могут понять это с первого взгляда.

Вам нужно показать пользователям, что означает их выражение, *прежде*, чем они его сохранят. Описание типа «В 09:00 в дни с 1 по 15, с понедельника по пятницу» стоит больше, чем ссылка на всплывающую подсказку. на crontab.guru.

API синтаксического анализатора cron Botoi выполняет три вещи в одном запросе POST: проверяет выражение, генерирует удобочитаемое описание и возвращает время следующего запланированного выполнения. Нет хрона библиотеки для установки, логика синтаксического анализа не требуется поддерживать.

Конечная точка синтаксического анализа

Отправьте выражение 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 и отдельный parts разбито по полям. Вы можете отобразить описание прямо в пользовательском интерфейсе и использовать nextRuns массив для предварительного просмотра предстоящих казней.

Получите больше предстоящих запусков

Если вам нужно более пяти дат предварительного просмотра или вас интересует только расписание, а не описание, используйте /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"
    ]
  }
}

Обратите внимание на разницу между 27 марта (пятница) и 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 отвечает менее чем за 50 мс с периферии Cloudflare, поэтому предварительный просмотр кажется мгновенным, как только запрос уходит.

Версия 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 * * * * Каждый час
0 9 * * MON-FRI В 09:00 с понедельника по пятницу
0 0 1 * * В полночь 1-го числа каждого месяца
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 по-разному. Один API дает вам единственный источник истины.
  • Удобочитаемые описания бесплатно. Генерация естественного языка из cron синтаксис сложнее, чем анализ расписания. API обрабатывает оба запроса за один вызов.
  • Мгновенный предварительный просмотр для пользователей. Реакция на фронт менее 50 мс обеспечивает проверку в реальном времени практично, даже при каждом нажатии клавиши с устранением дребезга.

FAQ

Поддерживает ли API анализатора cron нестандартные выражения, такие как @daily или @weekly?
Да. Конечная точка синтаксического анализа принимает как стандартные выражения cron из пяти полей, так и распространенные сокращенные псевдонимы, такие как @yearly, @monthly, @weekly, @daily и @hourly. Ответ нормализует их в стандартный формат пяти полей.
В каком часовом поясе находятся временные метки nextRuns?
Все временные метки в ответе указаны в формате UTC (формат ISO 8601). Преобразуйте их в локальный часовой пояс пользователя на стороне клиента, используя Intl.DateTimeFormat или такую ​​библиотеку, как date-fns.
Существует ли ограничение на количество следующих запусков, которые я могу запросить?
Конечная точка /v1/cron/next принимает параметр count. Вы можете запросить до 100 предстоящих сеансов за один звонок. Значение по умолчанию — 5, если вы опустите этот параметр.
Нужен ли мне ключ API для использования анализатора cron?
Нет. Анонимный доступ возможен со скоростью 5 запросов в минуту с ограничением скорости по IP. Для более высокой пропускной способности зарегистрируйтесь для получения ключа API на сайте botoi.com/api.
Могу ли я использовать названия дней, например ПН-ПТ, в выражениях cron?
Да. Анализатор поддерживает трехбуквенные сокращения дня (ВС, ПН, ВТ, СР, ЧТ, ПТ, СБ) и сокращения месяцев (ЯНВАРЬ-ДЕКАБРЬ) в соответствующих полях.

Начните разработку с botoi

150+ API-эндпоинтов для поиска, обработки текста, генерации изображений и утилит для разработчиков. Бесплатный тариф, без банковской карты.