Как выбрать запись маршрута 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-код.

    Часто задаваемые вопросы