Реализация Slug (Человекопонятных идентификаторов)
Новое в версии 1.1
Поле slug (читаемый идентификатор) добавлено в версии 1.1 для создания удобных адресов страниц. Slug является опциональным дополнением к обязательному UUID (уникальному идентификатору записи).
Что такое slug?
Slug — это человекопонятный идентификатор объекта для использования в URL. В отличие от UUID (например, 7c9e6679-7425-40de-944b-e07fc1f90ae7), slug содержит читаемое название (например, big-hall или tchaikovsky-symphony-5).
Преимущества slug:
- Поисковая оптимизация (SEO) — поисковые системы лучше индексируют читаемые адреса
- Удобство для пользователей — адрес легко запомнить и набрать вручную
- Социальные сети — ссылки выглядят привлекательнее при публикации
- Аналитика — читаемые адреса упрощают анализ трафика
Почему UUID остается обязательным:
- Постоянство — UUID никогда не меняется, даже при переименовании объекта
- Уникальность — UUID v4 гарантирует глобальную уникальность
- Синхронизация — централизованный реестр использует UUID для идентификации
- Независимость — UUID не зависит от названия объекта
⚠️ Важно:
Slug — это опциональное дополнение, а не замена UUID. Нельзя работать только на slug без UUID. UUID остается обязательным полем для всех объектов.
Формат slug
Slug должен соответствовать следующим требованиям:
- Только латинские буквы (a-z) — кириллица не допускается
- Только строчные буквы (lowercase) — UPPERCASE не допускается
- Цифры (0-9) — допускаются
- Дефисы (-) — используются для разделения слов
- Без специальных символов — запрещены пробелы, подчеркивания, точки и т.д.
- Длина — рекомендуется 3-100 символов
Примеры правильных slug:
big-hallsymphony-orchestratchaikovsky-symphony-52026-03-15-concertyuri-temirkanov
Примеры неправильных slug:
Большой-зал❌ (кириллица)Big-Hall❌ (заглавные буквы)big_hall❌ (подчеркивание вместо дефиса)big hall❌ (пробелы)big.hall❌ (точка)
308 Permanent Redirect
Slug-версия URL должна делать 308 Permanent Redirect на UUID-версию URL. Это гарантирует, что при изменении slug старые ссылки продолжат работать.
Что такое 308?
308 Permanent Redirect — это HTTP-статус, который говорит браузеру и поисковым системам:
- Ресурс постоянно переехал на новый URL
- Используй тот же HTTP-метод (GET остается GET)
- Обнови закладки и поисковый индекс
Пример работы:
GET /data/places/big-hall.jsonld HTTP/1.1
Host: filarmonia.online
HTTP/1.1 308 Permanent Redirect
Location: /data/places/7c9e6679-7425-40de-944b-e07fc1f90ae7.jsonld
Почему 308, а не 301?
- 308 — сохраняет метод запроса (GET → GET, POST → POST)
- 301 — может изменить POST на GET (устаревшее поведение)
Для программного интерфейса (REST API) правильно использовать 308.
Реализация на сервере
Apache (.htaccess)
RewriteEngine On
# Редирект slug на UUID для places
RewriteRule ^data/places/([a-z0-9-]+)\.jsonld$ /resolve-slug.php?type=place&slug=$1 [L]
# Редирект slug на UUID для events
RewriteRule ^data/events/([a-z0-9-]+)\.jsonld$ /resolve-slug.php?type=event&slug=$1 [L]
# Редирект slug на UUID для performers
RewriteRule ^data/performers/([a-z0-9-]+)\.jsonld$ /resolve-slug.php?type=performer&slug=$1 [L]
resolve-slug.php:
<?php
$type = $_GET['type'] ?? '';
$slug = $_GET['slug'] ?? '';
// Получить UUID из базы данных по slug
$uuid = getUuidBySlug($type, $slug);
if ($uuid) {
// 308 Permanent Redirect на UUID-версию
header("HTTP/1.1 308 Permanent Redirect");
header("Location: /data/{$type}s/{$uuid}.jsonld");
exit;
} else {
// Если slug не найден, вернуть 404
header("HTTP/1.1 404 Not Found");
echo json_encode(["error" => "Slug not found"]);
exit;
}
function getUuidBySlug($type, $slug) {
// Ваша логика получения UUID из БД
// Пример:
// SELECT uuid FROM places WHERE slug = :slug
// ...
}
?>
Nginx
server {
location ~ ^/data/(places|events|performers)/([a-z0-9-]+)\.jsonld$ {
set $type $1;
set $slug $2;
# Вызвать backend для получения UUID по slug
proxy_pass http://backend/resolve-slug?type=$type&slug=$slug;
# Или использовать Lua для прямого запроса к БД
}
}
Примеры использования
Пример 1: Place (Зал)
JSON-LD с slug:
{
"@context": [
"https://schema.org",
"https://id.filarmonia.online/spec/1.1/context.jsonld"
],
"@type": "MusicVenue",
"@id": "https://filarmonia.online/places/7c9e6679-7425-40de-944b-e07fc1f90ae7",
"uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"slug": "big-hall",
"name": "Большой зал"
}
Доступные URL:
GET /data/places/7c9e6679-7425-40de-944b-e07fc1f90ae7.jsonld→ 200 OK (основной)GET /data/places/big-hall.jsonld→ 308 → UUID-версия
Пример 2: Event (Концерт)
{
"@type": "MusicEvent",
"@id": "https://filarmonia.online/events/a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
"uuid": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
"slug": "tchaikovsky-symphony-5",
"name": "Симфония № 5 П.И. Чайковского"
}
Доступные URL:
GET /data/events/a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d.jsonld→ 200 OKGET /data/events/tchaikovsky-symphony-5.jsonld→ 308 → UUID-версия
Лучшие практики
- Используйте дефисы для разделения слов —
big-hall, а неbighall - Включайте дату для событий —
2026-03-15-concertделает slug уникальным - Транслитерируйте кириллицу — "Большой зал" →
big-hallилиbolshoy-zal - Не дублируйте UUID в slug — slug должен быть читаемым, а не копией UUID
- Сохраняйте историю slug — при изменении slug старый должен продолжать редиректить
- Проверяйте уникальность — slug должен быть уникальным в рамках типа объекта
Часто задаваемые вопросы
Можно ли работать только на slug без UUID?
Нет. UUID обязателен. Slug — это опциональное дополнение для SEO.
Что произойдет если я изменю slug?
Старый slug должен продолжать редиректить на UUID-версию. UUID остается неизменным, поэтому данные останутся доступными.
Нужно ли делать slug для всех объектов?
Нет, slug опционален. Рекомендуется добавлять для публичных объектов (залы, события, исполнители), которые часто публикуются в соцсетях.
Можно ли использовать кириллицу в slug?
Нет. Slug должен содержать только латинские буквы. Используйте транслитерацию или английский перевод названия.