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

Ответ

Основная идея 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 и т.д.
  • Классы-представления: Вместо функций можно использовать классы для лучшей организации кода.

Ответ 18+ 🔞

Смотри, ну это ж классика, блядь! Весь этот ваш веб, сука, на маршрутизации стоит, а она, по сути, проще пареной репы. Ёпта, сейчас разжую.

Основная фишка роутера — это как в бардачке машины: есть путь — /сигареты, и есть функция — выдать_сигареты. Надо просто их сопоставить, и всё, пиздец. Самый примитивный способ — тупо словарь и декоратор, вот и вся магия.

Из чего это говно состоит:

  1. Хранилище маршрутов: Обычный словарь, ёбта! Ключ — это путь (типа "/about"), а значение — сама функция, которая будет этот запрос обрабатывать. Всё, больше нихуя.
  2. Декоратор-регистратор: Чтоб не писать руками url_registry['/about'] = about_func, придумали декоратор. Красиво, удобно, в рот меня чих-пых.
  3. Диспетчер (или обработчик): Это такой главный мудила, который получает запрос, смотрит на путь, лезет в словарь, ищет функцию и говорит ей: «На, еби!». Не нашёл — ну, извини, 404, пошёл нахуй.

Вот смотри, как это в коде выглядит, всё по полочкам:

# 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', '/')
    # Ищем функцию в нашем святом словаре
    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')

А дальше что, блядь?

Ну а дальше начинается веселье, ёпта! Эту простую хуйню можно улучшать до овердохуища:

  • Динамические пути: Чтобы не для каждого user/1, user/2 писать отдельный маршрут. Тут уже регулярки или свои парсеры подключают, чтоб <id> вытаскивать.
  • HTTP-методы: Чтобы GET /users и POST /users делали разное. Тут словарь уже посложнее будет, не просто путь, а (путь, метод).
  • Классы вместо функций: Когда обработчиков дохуя, их в классы засовывают для порядка, чтоб не один большой файл с функциями был, а то с ума сойдёшь.