Главная страница   /   9.2. Создание схемы URL-адреса (ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

Джеффри Палермо

9.2. Создание схемы URL-адреса

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

Вот несколько рекомендаций для проектирования схемы URL:

  • Создавайте простые, чистые URL.
  • Создавайте интуитивно понятные URL.
  • Дифференцируйте запросы с помощью URL-параметров.
  • Не открывайте id из баз данных везде, где это возможно.
  • Старайтесь добавлять дополнительную информацию.

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

Создаем простые, чистые URL

Самый полезный прием при разработке схемы URL - отстраниться от приложения и рассмотреть схему с точки зрения конечного пользователя. Не обращайте внимания на архитектуру, которую вы должны реализовать в URL. Помните, что с помощью маршрутизации вы можете полностью отделить URL-адреса от нижележащей реализации. Чем более простой и чистой вы сделаете постоянную ссылку, тем более удобным будет ваш сайт.

Постоянные и "глубокие" ссылки

За последние несколько лет стали очень популярными постоянные ссылки, и теперь важно их учитывать при разработке схемы URL. Постоянная ссылка - это просто неизменяемая прямая ссылка на ресурс (страницу) в пределах одного сайта или приложения. Например, в блоге ссылка на отдельную публикацию чаще всего будет постоянной, такой как http://example.com/blog/post-1/hello-world.

Давайте рассмотрим в качестве примера приложение для управления событиями. Используя Web Forms, мы могли бы в конечном итоге получить ссылку вроде этой:

http://example.com/eventmanagement/events_by_month.aspx?year=2011&month=4

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

http://example.com/events/2011/04

Преимущество данного подхода в том, что у нас будет однозначный иерархический формат даты в URL. Однако из-за этого возникает один интересный вопрос: что произойдет, если в URL отсутствует сегмент "04"? Что имел в виду пользователь? Это описывается как восприятие URL.

Создавайте интуитивно понятные URL

При разработке схемы URL стоит учитывать то, как конечный пользователь воспринимает URL и как может изменять или «подстраивать» ссылку, чтобы изменить отображаемую дату. Было бы разумно предположить, что удаление параметра "04" из следующего URL представит все события, произошедшие в 2011 году:

http://example.com/events/2011/04

Следуя той же логике, можно предложить более понятный список роутов, показанный в таблице 9-2.

Таблица 9-2: Частичная схема URL для приложения управления событиями
URL Описание
http://example.com/events Отображает все события
http://example.com/events/<year> Отображает все события за определенный год
http://example.com/events/<year>/<month> Отображает все события за определенный месяц
http://example.com/events/<year>/<month>/<date> Отображает все события за определенный день

Использовать гибкую схему URL, конечно, замечательно, но это может привести к тому, что у вас в приложении будет огромное число потенциальных URL-адресов. Когда вы создаете представление для приложения, вы всегда должны предоставлять соответствующую навигацию; помните, что она не обязана содержать ссылку на каждую возможную комбинацию URL на каждой странице. Будет отлично, если некоторые страницы будут появляться в ответ на случайную попытку подстроить URL.

Подстройка URL-адресов дает пользователям больше возможностей. С датами ее легко использовать, но как быть со ссылками, в которых используются имена страниц?

Слеш или тире?

По общему соглашению, если для разделения параметров используется слеш, URL должен быть действительным, если параметры опущены. Если пользователю представлен URL /events/2008/04/01/, было бы разумно предположить, что удаление последнего параметра day может привести к увеличению объема данных, которые выводит эта ссылка. Если это не желательно в вашей схеме URL, попробуйте использовать тире вместо слеша, потому что /events/2008-04-01/ не предполагает такую же подстройку.

Дифференцируйте запросы с помощью параметров URL

Давайте расширим роуты и разместим события по категориям. С точки зрения пользователя, наиболее удобным URL будет что-то вроде этого:

http://example.com/events/aspnet-usergroup-meeting

Но здесь появляется проблема! У нас уже есть роут, который соответствует схеме /events/<что-то еще>, и он используется для вывода списка событий за конкретный год, месяц или день. Так как мы сейчас собираемся использовать/events/<что-то еще>, чтобы выводить категории? Второй сегмент роута теперь может означать нечто совершенно иное, и это противоречит существующему роуту. Когда этот URL поступает в систему маршрутизации, она должна обрабатывать этот параметр как категорию или дату?

К счастью, система маршрутизации в ASP.NET MVC позволяет применять условия. С синтаксисом условий можно познакомиться далее, а сейчас достаточно сказать, что мы можем использовать регулярные выражения для гарантии того, что роуты соотносятся с определенными шаблонами параметров. Это значит, что мы можем использовать единый роут, что позволит передать запросы типа /events/2011-01-01 в действие, которое выводит события по дате, а запрос типа /events/asp-net-mvc-in-action - в действие, которое выводит события по категории. Эти URL не противоречат друг другу, потому что мы различаем их на основе того, какие символы в них содержатся.

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

Следующий принцип, который мы разберем, это размер URL. Для URL размер имеет значение, и чем меньше URL, тем лучше.

Не открывайте ID из баз данных везде, где это возможно

Когда мы проектируем постоянную ссылку на определенное событие, основное требование заключается в том, что URL должен идентифицировать событие как уникальное. Определенно, у нас уже есть уникальный идентификатор для каждого объекта, который мы получаем из базы данных в виде первичного ключа. Обычно это целое число, которое автоматически назначается объекту базой данных, начиная с 1. Поэтому кажется очевидным, что схема URL должна включать в себя ID базы данных.

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

http://example.com/events/87

К сожалению, число 87 ничего не значит ни для кого, кроме администратора базы данных. Следует избегать использования в URL ID, генерируемых базой данных, везде, где это возможно. Это не значит, что вы не можете использовать целые числа в URL там, где они релевантны, но попробуйте придать им смысл.

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

http://example.com/events/houstonTechFest2010

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

Это отличная техника, но что делать, если у вас нет уникального имени для ресурса? Что если вам нужно разрешить повторяющиеся имена, и единственный уникальный идентификатор – это ID базы данных? Наш следующий прием покажет, как использовать и идентификатор, и текстовое описание для создания уникальных и удобочитаемых URL.

Добавляйте дополнительную информацию

Если вы должны использовать ID базы данных в URL, попробуйте добавить дополнительную информацию, которая не имеет никакой другой цели, кроме той, чтобы сделать URL читаемым. Рассмотрим URL для конкретной сессии в нашем приложении для событий. Свойство Title не обязательно будет уникальным, и заставлять пользователей добавлять текстовый идентификатор сессии было бы непрактично. Если к нему добавить слово session просто для удобства чтения, URL будет выглядеть примерно так:

http://example.com/houstonTechFest2010/session-87

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

http://example.com/houstonTechFest2010/session-87/an-introduction-to-mvc

Он более наглядный, и параметр session-87 по-прежнему указывает на сессию с помощью идентификатора базы данных. Мы также могли бы преобразовать имя сессии в более подходящий для URL формат, но это мелочи.

Поисковая оптимизация (SEO)

Стоит отметить значение хорошо продуманных ссылок для оптимизации сайта для поисковых систем. Хорошо известно, что размещение релевантных ключевых слов в URL напрямую влияет на поисковый рейтинг, поэтому при разработке схем URL имейте в виду следующие советы.

  • Используйте описательные, простые, широко используемые слова в названиях контроллеров и действий.Постарайтесь использовать релевантные ключевые слова, которые вы хотели бы применить к данной странице.
  • Замените все пробелы (которые кодируются в URL неприглядными 20%) на тире (-), когда создаете роут с текстовыми параметрами. Некоторые разработчики используют символы подчеркивания, но тире рассматриваются поисковыми системами как символы разделения слов.
  • Вырежьте все ненужные знаки препинания и текст из строковых параметров.
  • По возможности, включайте в URL дополнительную значимую информацию. Такая дополнительная информация, как заголовки и описания, предоставляет контекст и ключевые слова для поисковых систем, что может улучшить релевантность сайта.

Принципы маршрутизации, описанные в этом разделе, помогут вам определиться с выбором URL для вашего приложения. Определитесь со схемой URL до того, как запустить сайт, потому что URL-адреса являются точкой входа в приложение. Если у вас есть ссылки с других сайтов, и вы измените URL-адреса, вы потеряете эти ссылки и трафик с других сайтов.

Архитектура REST

Архитектурный стиль REST (англ. REST или RESTful architecture) - последняя тенденция в веб-разработке. REST означает representational state transfer (передача репрезентативного состояния). Название не говорящее, но определенный смысл за ним все-таки стоит.

REST основывается на принципе, что каждое значимое "нечто" в приложении должно быть адресуемым ресурсом. Ресурсы доступны через единый, общий URI, и для всех ресурсов доступен простой набор операций. Но здесь появляется интересная проблема. Используя менее известные методы HTTP (которые также называют verbs) PUT и DELETE в дополнение к вездесущим GET и POST, вы можете создать архитектуру, где URL указывает на ресурс ("нечто", о котором идет речь) и метод HTTP означает метод (что делать с этим "нечто").

Например, если вы используете URI /speakers/5 с методом GET, при просмотре в браузере вы увидите репрезентацию докладчика как HTML-документ. Другие возможные операции показаны в следующей таблице:

URL Метод Действие
/sessions GET Вывести все сессии
/sessions POST Добавить новую сессию
/sessions/5 GET Показать сессию с ID 5
/sessions/5 PUT Обновить сессию с ID 5
/sessions/5 DELETE Удалить сессию с ID 5
/sessions/5/comments GET Получить список комментариев для сессии с ID 5

REST полезен не только как архитектура для рендеринга веб-страниц, он также является средством создания многократно используемых сервисов. Те же самые URL могут предоставить данные для вызова Ajax или другого приложения. В некотором смысле, REST – это реакция против более сложных сервисов на основе SOAP, так как сложность SOAP часто приносит больше проблем, чем решений.

Если вы раньше использовали Ruby on Rails и восхищались его встроенной поддержкой REST, вы будете разочарованы, обнаружив, что ASP.NET MVC таковой не имеет. Но, благодаря расширяемости платформы, реализовать REST-архитектуру не трудно.

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