Реализация 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 и полную поддержку после внедрения. Закажите реализацию фидов — получите готовый код с документацией и поддержкой.







