Рекомендации по API
Лучшие практики, рекомендации по кэшированию и чего ожидать при интеграции с RadioMV API.
Обзор
RadioMV API — это статические JSON-файлы, размещённые на Cloudflare. Это означает:
- Аутентификация не требуется
- Нет ограничений частоты запросов
- Быстрая доставка через глобальную edge-сеть
- Высокая доступность
Что стоит делать
Всегда берите 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 |
Лучшие практики реализации
- Храните локальную копию — включите резервный JSON в сборку приложения для офлайн-режима
- Загружайте по условию — сравнивайте
config.versionилиlastUpdatedперед обработкой - Обрабатывайте сбои мягко — если загрузка не удалась, используйте кэш и не падайте
- Учитывайте часовой пояс — всё время расписаний указано в
America/Los_Angeles - Сначала HLS — проверяйте
audioPriority, но предпочитайте HLS для лучшей совместимости - Проверяйте
isMain— фильтруйте по этому флагу при показе основного списка станций
Пример проверки версии
// Умная загрузка с проверкой версии
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; // Откат к кэшу
}
}
Чего делать не стоит
Избегайте типичных ошибок
Соблюдение этих рекомендаций сохранит вашу интеграцию стабильной и быстрой.
Чего избегать
- Не «зашивайте» URL расписаний — всегда берите их из
appv2.jsonчерезstationScheduleUrl - Не опрашивайте постоянно — достаточно одной загрузки за сеанс работы приложения или раз в день
- Не «зашивайте» ID станций — всегда берите их из
appv2.json, состав станций может меняться - Не игнорируйте
schemaVersion— смена мажорной версии означает несовместимые изменения - Не считайте все поля обязательными — некоторые поля необязательны (например,
artworkUrl16x9,stationScheduleUrl) - Не разбирайте названия дней — дни задаются числами (0-6), не строками
- Не рассчитывайте на 12-часовой формат — время в 24-часовом формате
- Не полагайтесь на порядок в массиве — сортируйте расписания по
startTimeперед показом
Чего ожидать
Частота обновлений
| Тип изменения | Частота | Примеры |
|---|---|---|
| Обновления обложек | По сезонам (~4 раза в год) | Праздничные и сезонные оформления |
| Изменения расписаний | Редко (~3 раза в год) | Новые программы, смена времени эфира |
| Изменения URL потоков | Очень редко | Обновления инфраструктуры |
| Новые станции | Очень редко | Запуск нового языка или канала |
| Изменения схемы | Очень редко | Новые поля, изменение структуры |
Политика несовместимых изменений
Для файлов расписаний мы придерживаемся семантического версионирования:
- Мажорная версия (2.0.0) — несовместимые изменения: поля переименованы, удалены или сменили тип. Требуется обновление.
- Минорная версия (1.1.0) — новые необязательные поля. Обратная совместимость сохраняется.
- Патч-версия (1.0.1) — только документация. Изменений в коде не требуется.
Обратная совместимость
Мы стремимся сохранять обратную совместимость. Новые поля добавляются как необязательные. Существующие поля не удаляются без смены мажорной версии.
Доступность
- Файлы раздаются через CDN Cloudflare
- Глобальные edge-узлы для быстрого доступа
- Плановых окон обслуживания нет
- Всегда держите резервную копию в кэше приложения
Обработка ошибок
Рекомендуемый шаблон
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:
- Сначала посмотрите эту документацию
- Изучите приведённые примеры кода
- Свяжитесь с нами по контактам из раздела settings в
appv1.json