Как выбрать запись маршрута REST API из таблицы БД
При разработке REST-сервисов часто возникает задача хранения маршрутов (роутов) в базе данных. Это позволяет администраторам через веб-интерфейс добавлять новые эндпоинты без изменения кода. Однако когда нужно обработать входящий запрос, например, /rest/v1.0.0/users/group/1/count/10, встаёт вопрос: как из таблицы с маршрутами получить только нужную запись (ID=3), не выгружая все строки и не выполняя поиск регулярными выражениями в PHP?
Проблема: поиск маршрута по шаблону
Типичная таблица routes содержит столбцы: id, pattern (шаблон URL), method, controller. Пример шаблона: /rest/v1.0.0/users/group/{id}/count/{limit}. При запросе /rest/v1.0.0/users/group/1/count/10 необходимо найти запись, чей шаблон совпадает с переданным путём. Простой SQL-запрос по точному совпадению не подходит, так как URL содержит динамические параметры (1, 10).
Решение: SQL-фильтрация с использованием регулярных выражений
Большинство современных СУБД (MySQL, PostgreSQL) поддерживают регулярные выражения прямо в запросе. Вам нужно преобразовать шаблон маршрута в регулярное выражение и выполнить поиск. Например, в MySQL используйте оператор REGEXP:
SELECT * FROM routes WHERE '/rest/v1.0.0/users/group/1/count/10' REGEXP pattern;Но здесь важно, чтобы в таблице шаблон хранился уже в виде регулярного выражения. Если шаблон содержит плейсхолдеры {id}, их нужно заранее заменить на [0-9]+ или .+ при вставке. Тогда запрос вернёт только одну строку - с ID=3, если её шаблон совпадает.
Пример для PostgreSQL
В PostgreSQL используйте оператор ~:
SELECT * FROM routes WHERE '/rest/v1.0.0/users/group/1/count/10' ~ pattern;Такой подход полностью исключает перебор всех записей на стороне PHP - база данных сама находит совпадение по регулярному выражению.
Альтернативный подход: нормализация маршрутов
Если вы не хотите использовать регулярные выражения в SQL, можно нормализовать URL и шаблон: разбить путь на сегменты и сравнивать их по частям. Например, хранить шаблон как /rest/v1.0.0/users/group/*/count/*, а при запросе заменять динамические сегменты на * и искать точное совпадение. Это быстрее, но менее гибко.
Рекомендации по оптимизации
- Индексируйте столбец pattern - для ускорения поиска по регулярным выражениям.
- Используйте кэширование - сохраняйте найденный маршрут в кэше (Redis, Memcached) на время.
- Проверяйте уникальность шаблонов - избегайте конфликтов, когда несколько маршрутов совпадают с одним URL.
Заключение
Получить из таблицы только нужную запись маршрута REST API без перебора всех строк можно с помощью SQL-регулярных выражений. Это простое и эффективное решение, которое переносит логику сопоставления на уровень базы данных, снижая нагрузку на PHP-код.