См.также
Идея маршрута (англ. - route) впервые появилась в Ruby on Rails и быстро обрела популярность в других веб-фреймворках. Также концептуально очень близкой системой является URLConf в Django. В последующих разработках наиболее мощной реализацией данной идеи, вероятно, является http://routes.groovie.org/, используемая в Pylons.
Маршруты отвечают за ключевую проблему веб-разработки: сопоставление кода и
URL. Например, какой код должен отвечать за обработку запросов по адресу
«/2008/01/08» или «/login»? Во многих фреймворках используется
фиксированная система диспетчеризации, например «/A/B/C» означает прочитать
файл «C» в каталоге «B» (например /auth/login.php
или
/cgi-bin/hello.cgi
), или вызвать метод «С» класса «B» в модуле «A».
Это работает прекрасно до тех пор, пока не возникает необходимости в реорганизации кода, и выясняется, что закладки пользователей стали недействительны. Кроме того, если вы хотите переделать адреса (например, создать раздел в подразделе), то нужно изменить уже отлаженную логику по генерации ссылок внутри сайта.
Маршруты предлагают иной подход. Вы определяете шаблоны URL и связываете их со своим кодом. Если вы измените свое решение по поводу конкретного URL, то просто поменяйте шаблон URL - код по-прежнему будет работать отлично, и не понадобится менять какую-либо логику.
Регулярные выражения дают огромные возможности для обработки URL-путей, но из-за ограничений, описанных в стандарте RFC 1738, большинство из них не нужны, при этом использование регулярных выражений затрудняет читабельность кода. Более современный подход придуманный Ruby on Rails это использовать технологию сопоставление с образом. Рассмотрим отличия на примере нашего блога:
Примечание
Исходный код доступен по адресу:
Предупреждение
Примеры работают только в Python3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | from views import BlogRead, BlogIndex, BlogCreate, BlogDelete, BlogUpdate
from wsgi_basic_auth import BasicAuth
# third-party
import selector
def make_wsgi_app():
passwd = {
'admin': '123'
}
# BasicAuth applications
create = BasicAuth(BlogCreate, 'www', passwd)
update = BasicAuth(BlogUpdate, 'www', passwd)
delete = BasicAuth(BlogDelete, 'www', passwd)
# URL dispatching middleware
dispatch = selector.Selector()
dispatch.add('/', GET=BlogIndex)
dispatch.prefix = '/article'
dispatch.add('/add', GET=create, POST=create)
dispatch.add('/{id:digits}', GET=BlogRead)
dispatch.add('/{id:digits}/edit', GET=update, POST=update)
dispatch.add('/{id:digits}/delete', GET=delete)
return dispatch
if __name__ == '__main__':
from paste.httpserver import serve
app = make_wsgi_app()
serve(app, host='0.0.0.0', port=8000) |
Регулярные выражения | Сопоставление с образом |
---|---|
/ | / |
/article/add | /article/add |
^/article/(?P<id>d+)/$ | /article/{id:digits} |
^/article/(?P<id>d+)/edit$ | /article/{id:digits}/edit |
^/article/(?P<id>d+)/delete$ | /article/{id:digits}/delete |