Реализация RSS и Atom подписки на контент
Отметим: когда сайт публикует новости, блог или обновления, читатели хотят получать их без лишних кликов. RSS и Atom-фиды решают эту задачу, но генерация валидного XML с автодискавери и кэшированием — нетривиальная задача. Мы берём это на себя и реализуем ленты, которые проходят валидацию W3C и поддерживаются всеми популярными агрегаторами.
Проблемы, которые решаем
При разработке фидов мы столкнулись с несколькими техническими сложностями. Во-первых, валидация: многие генераторы выдают XML с ошибками — неправильный mime-type, отсутствие обязательных элементов (guid, pubDate), неэкранированные символы. Во-вторых, производительность: при каждом запросе заново собирать 50 записей — нагрузка на БД. В-третьих, autodiscovery: без мета-тегов в
агрегаторы не находят фид. Кэширование реализовано через Redis или файловый кэш — выбор зависит от инфраструктуры проекта. TTL настраивается в конфиге и может быть изменён без деплоя.Как мы решаем типичные проблемы с фидами?
RSS 2.0 и Atom 1.0 — мы реализуем оба формата, чтобы покрыть 99% агрегаторов. Для валидации используем автоматические проверки: W3C Feed Validation Service и Feed Validator. Для производительности применяем кэширование на 15 минут с возможностью сброса при публикации.
Пример: валидация XML
Мы проверяем, что каждый item содержит guid, pubDate, title, link, description, а также необязательные элементы media:content и category. Если что-то отсутствует, фид не проходит в продакшен.Как мы генерируем фиды в Laravel?
Мы создаём контроллер FeedController с двумя методами: rss() и atom(). Они кэшируют сгенерированную разметку на 15 минут через Cache::remember(). Это снижает нагрузку в десятки раз. Если контент публикуется реже, TTL можно увеличить до 30–60 минут.
use Illuminate\Http\Response; use Illuminate\Support\Facades\Cache; class FeedController extends Controller { public function rss(): Response { $feed = Cache::remember('rss_feed', 900, fn() => $this->buildRss()); return response($feed, 200)->header('Content-Type', 'application/rss+xml; charset=utf-8'); } private function buildRss(): string { $articles = Article::published() ->latest('published_at') ->limit(50) ->get(); $lastBuild = $articles->first()?->published_at ?? now(); return view('feeds.rss', compact('articles', 'lastBuild'))->render(); } public function atom(): Response { $feed = Cache::remember('atom_feed', 900, fn() => $this->buildAtom()); return response($feed, 200)->header('Content-Type', 'application/atom+xml; charset=utf-8'); } } Шаблон RSS-фида включает обязательные элементы: title, link, description, language, lastBuildDate, а также <atom:link> для self-ссылки и <image> с логотипом. Для каждого item мы передаём title, link, guid (isPermaLink=true), pubDate, author, description, media:content (если есть изображение) и category для каждого тега.
<!-- resources/views/feeds/rss.blade.php --> <?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"> <channel> <title>{{ config('app.name') }}</title> <link>{{ url('/') }}</link> <description>{{ config('app.description') }}</description> <language>ru</language> <lastBuildDate>{{ $lastBuild->toRssString() }}</lastBuildDate> <atom:link href="{{ route('feed.rss') }}" rel="self" type="application/rss+xml"/> <image> <url>{{ url('/logo.png') }}</url> <title>{{ config('app.name') }}</title> <link>{{ url('/') }}</link> </image> @foreach($articles as $article) <item> <title><![CDATA[{{ $article->title }}]]></title> <link>{{ route('articles.show', $article->slug) }}</link> <guid isPermaLink="true">{{ route('articles.show', $article->slug) }}</guid> <pubDate>{{ $article->published_at->toRssString() }}</pubDate> <author>{{ $article->author->email }} ({{ $article->author->name }})</author> <description><![CDATA[{{ $article->excerpt }}]]></description> @if($article->cover_image) <media:content url="{{ $article->cover_url }}" medium="image"/> @endif @foreach($article->tags as $tag) <category>{{ $tag->name }}</category> @endforeach </item> @endforeach </channel> </rss> Atom-ленты обрабатываются агрегаторами на 20% быстрее, чем RSS, благодаря строгой структуре и обязательному guid.
Какие работы включены?
| Компонент | Описание |
|---|---|
| RSS 2.0 + Atom 1.0 | Полноценные ленты с media-контентом и категориями |
| Маршруты по категориям | /feed/{category} для фильтрации записей |
| Autodiscovery | Мета-теги в <head> для автоматического обнаружения |
| Кэширование | TTL от 15 до 60 минут с возможностью сброса |
| Валидация | W3C и Feed Validator перед деплоем |
| Документация | Описание маршрутов, форматов и конфигурации |
| Обучение | 1 час созвона для команды заказчика |
| Поддержка | 2 недели после внедрения |
Сравнение: RSS vs Atom — что лучше?
| Характеристика | RSS 2.0 | Atom 1.0 |
|---|---|---|
| Поддержка агрегаторами | 99% | 95% |
| Типы контента | Только текст | Встроенная поддержка HTML |
| Расширяемость | namespace-ами | namespace + стандарт |
| Обязательность guid | Рекомендуется | Обязателен |
| Дата публикации | pubDate (RFC 822) | published (ISO 8601) |
Atom более строгий и современный, но RSS остаётся обязательным минимумом. Мы рекомендуем реализовывать оба: это незначительно увеличивает объём кода, но покрывает всех пользователей.
Процесс работы
- Аналитика — изучаем структуру контента, какие модели публикуются, формат дат, наличие медиа.
- Проектирование — определяем маршруты, схему кэширования, формат категоризации.
- Реализация — пишем контроллер, шаблоны, маршруты, autodiscovery.
- Тестирование — проверяем валидацию, скорость загрузки, корректность данных в разных агрегаторах.
- Деплой и поддержка — настраиваем мониторинг (например, через UptimeRobot), обновляем при изменениях контента.
Сроки ориентировочно
Базовая реализация (RSS + Atom с кэшированием и autodiscovery) — от 0,5 до 1 дня. Если нужны фиды по категориям, тегам и кастомизация (например, дополнительные namespace) — от 1 до 2 дней. Стоимость рассчитывается индивидуально в зависимости от сложности. Свяжитесь с нами для точной оценки.
Почему стоит реализовать фиды у нас?
У нас за плечами многолетний опыт в веб-разработке и десятки успешных проектов с интеграцией фидов. Мы гарантируем валидность, отсутствие ошибок в XML и полную поддержку после внедрения. Закажите реализацию фидов — получите готовый код с документацией и поддержкой.







