Рекомендации по API

Лучшие практики, рекомендации по кэшированию и чего ожидать при интеграции с RadioMV API.

Обзор

RadioMV API — это статические JSON-файлы, размещённые на Cloudflare. Это означает:

Что стоит делать

Всегда берите URL расписаний из конфигурации приложения Никогда не «зашивайте» URL расписаний в код. Сначала загружайте appv2.json и используйте поле stationScheduleUrl каждой станции. Так ваше приложение автоматически получит правильные URL, когда мы выпустим новые версии.

Рекомендуемая последовательность

// 1. Загрузить конфигурацию (жёстко задаётся только этот URL)
const config = await fetch('https://api.radiomv.studio/appv2.json');
const data = await config.json();

// 2. Взять URL расписания из объекта станции
const station = data.stations.find(s => s.id === "1");
const scheduleUrl = station.stationScheduleUrl;

// 3. Загрузить расписание по URL из конфигурации
const schedule = await fetch(scheduleUrl);
const programs = (await schedule.json()).schedule;
Кэшируйте ответы разумно Файлы расписаний меняются ~3 раза в год. Конфигурация приложения меняется чаще, но тоже нечасто. Кэшируйте агрессивно.

Рекомендации по кэшированию

Файл Частота обновления Рекомендуемый кэш
appv1.json От недели до месяца 24 часа, проверять версию при запуске приложения
Файлы расписаний ~3 раза в год 7 дней, периодически проверять lastUpdated

Лучшие практики реализации

Пример проверки версии

// Умная загрузка с проверкой версии
async function fetchWithVersionCheck(url, cachedData) {
    try {
        const response = await fetch(url);
        const data = await response.json();

        // Для appv1.json
        if (data.config?.version === cachedData?.config?.version) {
            return cachedData; // Без изменений
        }

        // Для файлов расписаний
        if (data.lastUpdated === cachedData?.lastUpdated) {
            return cachedData; // Без изменений
        }

        return data; // Новые данные
    } catch (error) {
        return cachedData; // Откат к кэшу
    }
}

Чего делать не стоит

Избегайте типичных ошибок Соблюдение этих рекомендаций сохранит вашу интеграцию стабильной и быстрой.

Чего избегать

Чего ожидать

Частота обновлений

Тип изменения Частота Примеры
Обновления обложек По сезонам (~4 раза в год) Праздничные и сезонные оформления
Изменения расписаний Редко (~3 раза в год) Новые программы, смена времени эфира
Изменения URL потоков Очень редко Обновления инфраструктуры
Новые станции Очень редко Запуск нового языка или канала
Изменения схемы Очень редко Новые поля, изменение структуры

Политика несовместимых изменений

Для файлов расписаний мы придерживаемся семантического версионирования:

Обратная совместимость Мы стремимся сохранять обратную совместимость. Новые поля добавляются как необязательные. Существующие поля не удаляются без смены мажорной версии.

Доступность

Обработка ошибок

Рекомендуемый шаблон

async function loadStationData() {
    const CACHE_KEY = 'radiomv_app_config';

    try {
        // Пытаемся загрузить свежие данные
        const response = await fetch(
            'https://api.radiomv.studio/appv1.json',
            { timeout: 10000 }
        );

        if (!response.ok) {
            throw new Error(`HTTP ${response.status}`);
        }

        const data = await response.json();

        // Проверяем наличие ключевых полей
        if (!data.stations || !Array.isArray(data.stations)) {
            throw new Error('Invalid response structure');
        }

        // Кэшируем корректный ответ
        localStorage.setItem(CACHE_KEY, JSON.stringify(data));

        return data;

    } catch (error) {
        console.warn('Failed to fetch, using cache:', error);

        // Откатываемся к кэшу
        const cached = localStorage.getItem(CACHE_KEY);
        if (cached) {
            return JSON.parse(cached);
        }

        // Откатываемся к данным из сборки
        return require('./fallback-config.json');
    }
}

Работа с часовыми поясами

Всё время расписаний указано в America/Los_Angeles (тихоокеанское время). Чтобы показать его в локальном поясе пользователя:

function convertToLocalTime(timeStr, stationTimezone) {
    // timeStr — строка в формате "HH:MM"
    const [hours, minutes] = timeStr.split(':').map(Number);

    // Создаём дату в часовом поясе станции
    const today = new Date();
    const dateStr = today.toISOString().split('T')[0];

    const stationDate = new Date(
        `${dateStr}T${timeStr}:00`
    );

    // Форматируем в локальном поясе пользователя
    return stationDate.toLocaleTimeString('ru-RU', {
        hour: 'numeric',
        minute: '2-digit',
        timeZone: stationTimezone,
        timeZoneName: 'short'
    });
}

Поддержка

По вопросам и проблемам с API: