Маршрутизация запросов в Autodafé

    Autodafé — node.js фреймворк, начало читайте в этой статье: habrahabr.ru/blogs/nodejs/135089

    Основная часть статьи будет посвящена перенаправлению запросов в autodafe, формированию URL и т. п. Но для начала мне бы хотелось осветить общие принципы работы приложения с подключенными клиентами, для того чтобы было понятнее какую часть рабочего процесса мы будем обсуждать.

    Откуда берется пыль


    Начнем со схемы, отображающей подключение клиентов к приложению:



    На схеме можно увидеть несколько пользователей, которые пользуются различными устройствами и различными браузерами, которые в свою очередь подключаются к приложению по различным протоколам. (В данный момент к autodafe можно подключиться только по http и websockets)

    В приложении каждому подключению соответствует один Client. Client создается для каждого http запроса и подключения по websockets. Клиенты с одинаковым идентификатором сессии принадлежат одному экземпляру Session. Обычно одна сессия в приложение соответствует одному браузеру.

    Ну и для логического завершения на схеме приведен компонент “users”, который позволяет привязать различные сессии, прошедшие специальную авторизацию к одному объекту UserIdentity. Таким образом в приложении каждый объект UserIdentity соотносится к одному реальному пользователю.



    Куда деваются деньги


    Итак мы подходим к теме данной статьи: написание маршрутизации. Каждый Client, получив запрос, формирует его в особый вид и отправляет в Router. А он, в свою очередь, пользуясь таблицей маршрутизации ( Route map на схеме ) перенаправляет запрос в нужное действие нужного контроллера.

    Таким образом: каждый запрос по любому протоколу перенаправляется, пользуясь таблицей описанной в одном месте



    Таблица маршрутизации


    В таблице маршрутизации можно указывать:
    • само собой, маршруты перенаправления запросов к действию определенного контроллера
    • параметры для человекопонятных URL
    • методы и протоколы для которых доступны данные действия
    • перенаправление в зависимости от хоста с которого пришел запрос, на какой порт он пришел и т. д.

    Таблица маршрутизации служит не только для разбора пришедшего запроса, но и для формирования URL на сервере, что позволяет гибко менять вид URL, делая правки в одном месте.

    Контроллеры — это обычные классы. Действия — это методы. Ни один запрос не будет работать, если он не указан в таблице маршрутизации. Таким образом защищаются от вызова методы контроллера, не являющиеся действиями.

    Для следующих примеров можно взять приложение Hello World описанное в этой статье. Сейчас в секции router.rules конфигурационного файла лишь одно правило:

    router : {
      rules : {
        '' : 'site.index'
      }
    }
    

    Ключи секции rules соответствуют части url адреса, которая идет после названия хоста и до параметров запроса, так для url адреса www.example.com/messages/unread?user_id=5 эта часть равна messages/unread.

    Значения rules — это путь к действию, которое необходимо выполнить для данного запроса в виде 'контроллер.действие'

    router : {
      rules : {
        ''                : 'site.index',
        'messages/unread' : 'dialogs.show_unread_messages'
      }
    }
    


    Создание URL



    В коде контроллера для создания нужного URL надо пользоваться методом create_url:

    this.create_url( 'dialogs.show_unread_messages' ); // вернет '/messages/unread'
    

    Часто ссылки надо вставлять во вью, в качестве шаблонизатора сейчас используется dust, для него написана специальная функция url:

    <a href="{#url}dialogs.show_unread_messages{/url}">Непрочитанные сообщения</a>
    


    Передача параметров



    Создание ссылки внутри контроллера:

    this.create_url( 'dialogs.show_unread_messages', {
      user_id : 5
    } );                       // вернет '/messages/unread?user_id=5'
    

    Во вью:

    <a href='{#url user_id="5"}dialogs.show_unread_messages{/url}'>Непрочитанные сообщения</a>
    


    Засовываем параметры в путь



    Суть: превратить /messages/unread?user_id=5 в /messages/unread/user/5

    Секция rules:

    rules : {
      '/messages/unread/user/<user_id:\\d+>' : 'dialogs.dialogs.show_unread_messages'
    }
    

    Как видно, мы просто определяем название параметра и регулярное выражение которому он должен соответствовать. Ни в контроллере, ни во вью изменений делать не надо.

    Фильтруем запросы


    Некоторые действия необходимо выполнять, например, только если они пришли через POST запрос или по WebSockets. Это можно указать прямо в таблице.

    rules : {
      // запрос сработает только если придет через POST 
      'update_message' : 'dialogs.update_message | post'
    }
    

    Вместо post могут быть get, delete и ws. Последние ограничевает вызов только для действий, поступившим по WebSockets

    Методы можно группировать через запятую:

    rules : {
      // запрос сработает только если придет через POST
      'delete_message' : 'dialogs.delete_message | post, delete'
    }
    

    Пробелы не учитываются, так что можно спокойно выравнивать все в красивый вид

    Фильтруем запросы по доменному имени и порту

    rules : {
      'hostname:m.domain.com port:3000 /' : 'mobile.index'
    }
    

    Более подробно данная тема будет раскрыта в готовящемся сайте с документацией

    Спасибо за внимание.

    PS:


    Исходный код на github: autodafe
    Приследуйте фреймворк в твиттере @node_autodafe

    Если желаете принять участие в разработке или любым способом помочь в развитии фреймворка — пишите в личку или на jifeon at gmail.com
    Поделиться публикацией

    Похожие публикации

    Комментарии 0

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое