Как создать базовый URL-маршрутизатор для веб-фреймворка

«Как создать базовый URL-маршрутизатор для веб-фреймворка» — вопрос из категории Архитектура, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основная идея URL-маршрутизатора (роутера) — сопоставление URL-пути с функцией-обработчиком. В простейшем виде это можно реализовать с помощью словаря и декоратора.

Ключевые компоненты:

  1. Хранилище маршрутов: Словарь, где ключ — это URL-путь, а значение — ссылка на функцию-обработчик.
  2. Декоратор для регистрации: Удобный способ добавить новый маршрут в хранилище.
  3. Диспетчер: Функция, которая принимает входящий запрос, находит нужный обработчик в хранилище и вызывает его.

Пример реализации на Python:

# 1. Хранилище маршрутов
url_registry = {}

# 2. Декоратор для регистрации маршрутов
def route(path):
    def decorator(handler_func):
        # Добавляем пару "путь: функция" в словарь
        url_registry[path] = handler_func
        return handler_func
    return decorator

# Регистрация обработчиков
@route("/")
def home_page(request):
    return "200 OK", "This is the Home Page"

@route("/about")
def about_page(request):
    return "200 OK", "This is the About Page"

# 3. Диспетчер запросов
def handle_request(request):
    path = request.get('path', '/')
    # Ищем обработчик в реестре, иначе возвращаем 404
    handler = url_registry.get(path)
    if handler:
        return handler(request)
    return "404 Not Found", "Page not found"

# --- Эмуляция входящих запросов ---
request1 = {'path': '/'}
request2 = {'path': '/about'}
request3 = {'path': '/non-existent'}

print(handle_request(request1))  # ('200 OK', 'This is the Home Page')
print(handle_request(request2))  # ('200 OK', 'This is the About Page')
print(handle_request(request3))  # ('404 Not Found', 'Page not found')

Дальнейшие улучшения:

  • Динамические URL: Для путей вида /users/<id> используются регулярные выражения или парсеры шаблонов для извлечения параметров.
  • HTTP-методы: Хранилище можно усложнить, чтобы для одного URL были разные обработчики для GET, POST и т.д.
  • Классы-представления: Вместо функций можно использовать классы для лучшей организации кода.