Что делает URI крутым?
Крутой URI — тот, который не меняется.
Какие URI меняются?
URI не меняются: их меняют люди.

В теории у людей нет никаких причин менять URI (или прекращать поддержку документов), но на практике таких причин находится миллион.

В теории владелец доменного имени владеет всем пространством имён в этом домене и, соответственно, всеми URI в нём. Кроме банкротства, ничто не мешает владельцу домена сохранять это имя. И в теории пространство URI под доменным именем полностью подконтрольно владельцу, так что стабильность можно обеспечить любую. Практически единственная веская причина, по которой документ должен пропасть из веба — компания, владевшая доменом, закрылась или не может больше платить за сервер. Почему же тогда в мире столько битых ссылок? Отчасти дело просто в недостатке предусмотрительности. Вот распространённые объяснения, которые приходится слышать:

Мы просто реорганизовали сайт, чтобы сделать его лучше

Действительно ли старые URI невозможно было оставить работающими? Если так, то они были выбраны очень плохо. Новые URI стоит продумывать так, чтобы их можно было сохранить и после следующего редизайна.

У нас накопилось столько материала, что мы уже не отслеживаем, что устарело, что конфиденциально, а что актуально — и решили просто всё отключить

Тут есть понимание — через похожий период прошёл и W3C, когда пришлось тщательно фильтровать архивные материалы на конфиденциальность перед публикацией. Решение — предусмотрительность: фиксировать для каждого документа условия распространения, дату создания и, в идеале, дату истечения актуальности. Эти метаданные нужно сохранять.

Ну, оказалось, что файлы нужно было перенести...

Это одно из самых слабых объяснений. Многие не знают, что серверы вроде Apache дают гибкий контроль над связью между URI объекта и его реальным расположением в файловой системе. Пространство URI стоит воспринимать как абстрактное, идеально организованное пространство. Затем нужно построить отображение на ту реальность, которая используется для реализации. И настроить сервер соответствующим образом. Можно даже дописать части серверного кода, чтобы всё встало на место.

Джон больше не поддерживает этот файл, теперь этим занимается Джейн.

А что вообще имя Джона делало в этом URI? Файл лежал в его домашней директории? Понятно.

Раньше мы использовали для этого CGI-скрипт, а теперь — бинарную программу

Существует странное убеждение, что страницы, генерируемые скриптами, обязательно должны находиться в области "cgibin" или "cgi". Это раскрывает механизм работы сервера наружу. Меняется механизм (даже при том, что контент остаётся тем же) — и вот все URI поменялись.

Например, возьмём National Science Foundation:

NSF Online Documents
http://www.nsf.gov/cgi-bin/pubsys/browser/odbrowse.pl

Главная страница для поиска документов — совершенно очевидно не то, на что можно рассчитывать через несколько лет. "cgi-bin", "oldbrowse" и ".pl" — всё это указывает на детали текущей реализации. Для сравнения, если использовать эту страницу для поиска конкретного документа, попадаешь на такую же плохую

Report of Working Group on Cryptology and Coding Theory
http://www.nsf.gov/cgi-bin/getpub?nsf9814

индексную страницу документа, но сам HTML-документ выглядит намного лучше:

http://www.nsf.gov/pubs/1998/nsf9814/nsf9814.htm

Заголовок "pubs/1998" даёт любому будущему архивному сервису чёткую подсказку, что применялась схема классификации документов 1998 года. Хотя в 2098 году номера документов, вероятно, будут выглядеть иначе, такой URI вполне может остаться валидным, и NSF или организация, продолжающая архив, не будет за это стыдиться.

Я не думал, что URL должны быть постоянными — это же про URN

Это, вероятно, один из худших побочных эффектов дискуссий об URN. Некоторые считают, что раз ведутся исследования более постоянных пространств имён, можно быть настолько же небрежным с битыми ссылками, "потому что URN всё исправят". Тех, кто так думает, придётся разочаровать.

Большинство схем URN, что попадались на глаза, выглядят примерно как идентификатор организации, за которым следует либо дата и выбранная строка, либо просто выбранная строка. Это очень похоже на HTTP URI. Иными словами, если есть уверенность, что организация способна создавать долговечные URN, то доказательством этому будет создание таких URN уже сейчас — и использование их как HTTP URI. В самом протоколе HTTP нет ничего, что делает URI нестабильными. Нестабильна организация. Стоит создать базу данных, связывающую URN документа с текущим именем файла, и позволить веб-серверу использовать её для фактического извлечения файлов.

Если дошли до этого места, но нет времени, денег и контактов, чтобы заказать разработку программного обеспечения, остаётся следующее объяснение:

Мы бы хотели, но у нас просто нет подходящих инструментов

Вот это уже понятно и вызывает полное согласие. Веб-сервер должен мгновенно находить постоянный URI и возвращать файл, где бы он ни хранился в текущей запутанной файловой системе. Хорошо бы иметь возможность хранить URI внутри файла как проверку и постоянно синхронизировать базу данных с реальностью. Хорошо бы хранить связи между разными версиями и переводами одного документа, а также вести независимую запись контрольной суммы для защиты от случайного повреждения файла. Но веб-серверы из коробки просто не поддерживают такие функции. Когда создаётся новый документ, редактор должен спрашивать URI, а не сообщать его.

Нужна возможность менять владельца, права доступа, уровень архивирования, уровень безопасности документа в пространстве URI без изменения самого URI.

Жаль, но такого пока нет. Хотя движение в этом направлении есть. В W3C используется функциональность Jigedit (сервер Jigsaw, применяемый для редактирования), которая отслеживает версии, и ведутся эксперименты со скриптами создания документов. Разработчикам инструментов, серверов и клиентов стоит взять это на заметку!

Это весомая причина, применимая, например, ко многим страницам W3C, включая эту: так что стоит делать так, как здесь написано, а не так, как это сделано на практике.

Почему это должно меня волновать?

Когда URI на сервере меняется, никогда не удастся полностью проследить, у кого есть ссылки на старый адрес. Ссылки могли быть сделаны с обычных веб-страниц. Страницу могли добавить в закладки. URI могли написать от руки на полях письма другу.

Когда кто-то переходит по ссылке, а она не работает, доверие к владельцу сервера обычно падает. Плюс возникает раздражение — и эмоциональное, и практическое, из-за невозможности достичь цели.

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

Так что же делать? Проектирование URI

Обязанность веб-мастера — выделять URI, за которые можно ручаться и через 2 года, и через 20, и через 200 лет. Это требует продумывания, организации и обязательств.

URI меняются, когда в них заложена информация, которая со временем меняется. Критически важно, как они спроектированы. (Что, проектировать URI? Разве нужно продумывать URI? Да, придётся об этом подумать.) Проектирование в основном означает — исключать лишнее из адреса.

Дата создания документа — дата выпуска URI — это то, что не изменится. Она очень полезна для разделения запросов, использующих новую систему, от тех, что используют старую. Это удачный элемент для начала URI. Если документ хоть как-то датирован, даже если он представляет интерес и для будущих поколений, дата — хорошая точка отсчёта.

Единственное исключение — страница, которая специально сделана "последней" (latest) для организации в целом или большой её части.

http://www.pathfinder.com/money/moneydaily/latest/

это последняя на данный момент колонка "Money daily" в журнале "Money". Основная причина, по которой дата в этом URI не нужна — жизнь этого URI не должна пережить сам журнал. Концепция "сегодняшнего выпуска Money" исчезнет, если Money прекратит выходить. Для ссылки на конкретный контент правильнее вести на его отдельную страницу в архиве:

http://www.pathfinder.com/money/moneydaily/1998/981212.moneyonline.html

(Выглядит неплохо. Предполагает, что "money" будет означать одно и то же на протяжении всей жизни pathfinder.com. Есть избыточность в виде дублирования "98" и ненужного ".html", но в остальном URI довольно надёжный).

Что нужно исключить

Практически всё! После даты создания включение любой другой информации в имя — это заведомое создание проблем в будущем.

  • Имя автора — авторство может меняться с новыми версиями. Люди уходят из организаций и передают дела другим.
  • Тема. Это сложный момент. На первый взгляд всегда выглядит удачно, но меняется удивительно быстро. Об этом подробнее ниже.
  • Статус — директории типа "old", "draft" и подобные, не говоря уже о "latest" и "cool", встречаются повсюду в файловых системах. Статус документов меняется — иначе не было бы смысла в черновиках. Последней версии документа нужен постоянный идентификатор независимо от статуса. Статус не должен быть частью имени.
  • Уровень доступа. В W3C сайт делится на "доступ команды", "доступ участников" и "публичный доступ". Звучит логично, но документы начинаются как внутренние идеи, обсуждаются с участниками, а затем становятся публичными. Печально, если каждый раз при расширении доступа к документу все старые ссылки на него ломаются! Сейчас переходим на простую систему кодирования по дате.
  • Расширение файла. Очень распространённая ошибка. "cgi", и даже ".html" — это то, что со временем меняется. Через 20 лет для страницы может использоваться уже не HTML, но хочется, чтобы сегодняшние ссылки на неё продолжали работать. Канонический способ формирования ссылок на сайт W3C не использует расширение (как это сделать?).
  • Механизмы программного обеспечения. Стоит избегать в URI слов "cgi", "exec" и других явных указаний "вот какое ПО мы используем". Кто готов пожизненно обязаться писать CGI-скрипты именно на perl? Нет? Значит, убираем ".pl". В руководстве к серверу написано, как это сделать.
  • Имя диска — ну хватит уже! Но такое встречалось.

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

http://www.w3.org/1998/12/01/chairs

отчёт о протоколе заседания председателей W3C.

Темы и классификация по предмету

Этой опасности стоит уделить больше внимания, так как её труднее всего избежать. Обычно темы попадают в URI, когда документы классифицируются согласно структуре текущей работы. Эта структура со временем меняется. Названия разделов меняются. В W3C название "MarkUp" сначала поменяли на "Markup", а затем на "HTML", чтобы точнее отразить содержание раздела. Кроме того, стоит помнить, что часто это плоское пространство имён. Есть ли уверенность, что через 100 лет ничего не понадобится использовать повторно? За недолгую историю W3C понадобилось повторно использовать, например, названия "History" и "Stylesheets".

Это соблазнительный способ организации сайта — и вообще соблазнительный способ организации чего угодно, включая весь веб. Это отличное среднесрочное решение, но у него серьёзные недостатки в долгосрочной перспективе.

Отчасти причины этого лежат в философии смысла. Любой термин языка — потенциальная тема для группировки, и у каждого человека может быть своё представление о том, что он означает. Поскольку связи между темами скорее сетевые, чем древовидные, даже люди, согласные друг с другом по существу, могут выбрать разное древовидное представление. Это (неоднократно повторяемые) общие замечания об опасностях иерархической классификации как универсального решения.

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

Причина использовать тематическую область как часть URI в том, что ответственность за подпространства URI обычно делегируется, и тогда нужно имя для организационной единицы — подразделения, группы или чего-то ещё — отвечающей за это подпространство. Это привязывает URI к организационной структуре. Обычно это безопасно только когда защищено датой чуть выше по иерархии (левее в пути): "1998/pics" можно трактовать для сервера как "то, что мы в 1998 году понимали под pics", а не "то, что в 1998 году мы делали с тем, что сейчас называем pics".

Не забывайте про доменное имя

Это касается не только "пути" URI, но и имени сервера. Если для части контента используются отдельные серверы, стоит помнить: изменить это разделение впоследствии без разрушения множества ссылок будет невозможно. Классические доменные имена в стиле "вот какое ПО мы используем сейчас" — "cgi.pathfinder.com", "secure", "lists.w3.org". Они появляются для упрощения администрирования серверов. Отражает ли имя деления внутри компании, статус документа, уровень доступа или уровень безопасности — стоит быть очень, очень осторожным перед использованием более одного домена для более чем одного типа документов. Стоит помнить, что можно скрыть множество веб-серверов внутри одного видимого сервера с помощью редиректов и проксирования.

И, конечно, стоит задуматься о самом доменном имени. Если название компании не "soap", захочется ли называться "soap.com", даже когда линейка продуктов сменится на что-то совсем другое. (С извинениями перед текущим владельцем soap.com).

Заключение

Сохранить URI так, чтобы они оставались доступными через 2, 20, 200 или даже 2000 лет — явно не так просто, как кажется. Тем не менее по всему вебу веб-мастера принимают решения, которые создадут им серьёзные проблемы в будущем. Часто причина в том, что используются инструменты, задача которых — представить лучший сайт прямо сейчас, а никто не оценил, что случится со ссылками при изменениях. Мысль здесь такая: очень многое может меняться, а URI могут и должны оставаться неизменными. Но это возможно только если продумать их проектирование заранее.

См. также:

Примечание

Как убрать расширения файлов...

...из URI на практике, если сайт основан на файловом веб-сервере?

Например, при использовании Apache можно настроить согласование содержимого (content negotiation). Расширение файла (например, .png) остаётся на самом файле (например, mydog.png), но ссылка на веб-ресурс делается без него. Apache затем проверяет директорию на наличие всех файлов с таким именем и любым расширением и может выбрать наилучший вариант из набора (например, GIF и PNG). (Не нужно раскладывать разные типы файлов по разным директориям — более того, согласование содержимого не будет работать, если так сделать.)

  • Настроить сервер на согласование содержимого
  • Всегда ссылаться на URI без расширения

Ссылки с указанным расширением всё равно будут работать, но не позволят серверу выбирать лучший из доступных сейчас и в будущем форматов.

(На деле, mydog, mydog.png и mydog.gif — это три разных валидных веб-ресурса. mydog универсален по типу содержимого. mydog.png и mydog.gif — специфичны по типу содержимого.)

Конечно, если сервер строится с нуля, использование базы данных для связи постоянных идентификаторов с их текущей формой — очень чистое решение, хотя стоит остерегаться неограниченного роста этой базы.

Зал позора — история 1: Channel 7

В 1999 году страница http://www.whdh.com/stormforce/closings.shtml содержала информацию о закрытии школ из-за снегопада. Удобная альтернатива ожиданию, пока список прокрутится по нижней части телеэкрана! На неё стояла ссылка с личной домашней страницы. С приходом первого крупного снегопада 2000 года страница была открыта снова. На ней было написано:

"Список закрытий на .
На данный момент закрытий нет. Пожалуйста, проверьте позже, если погода потребует"

Не похоже на такую уж сильную бурю. Забавно, что дата отсутствует. Но если перейти на главную страницу сайта, там есть большая кнопка "school closings", ведущая на http://www.whdh.com/stormforce/, где перечислены множество закрытых школ.

Возможно, они сменили систему, получающую данные из основного списка — но менять URI для этого было совершенно не нужно.

Зал позора — история 2: Microsoft Netmeeting

Одним из удобных решений, появившихся с растущей зависимостью от веба, стала возможность встраивать в приложения ссылки обратно на сайт производителя. Эта возможность использовалась и злоупотреблялась в изрядной мере, но URL всё равно нужно оставлять неизменным. Буквально на днях при попытке перейти по ссылке из клиента Microsoft Netmeeting 2/что-то через меню "Help/Microsoft on the Web/Free stuff" сервер вернул ошибку 404 — not found. Возможно, к этому моменту её уже исправили...

Историческая справка: на рубеже XX и XXI веков, когда этот текст был написан, слово "cool" ("крутой") служило особым знаком одобрения, особенно среди молодёжи, обозначая модность, качество или уместность. В спешке занять территорию в DNS выбор доменного имени и пути URI иногда диктовался скорее видимой "крутостью", чем практичностью или долговечностью. Эта заметка — попытка направить энергию, стоящую за погоней за "крутостью", в более полезную сторону.