Erhalten Sie Zugang zu diesem und mehr als 300000 Büchern ab EUR 5,99 monatlich.
Опытные программисты, выросшие вместе со Всемирной паутиной, не уделяли идеям гипермедиа особого внимания. А молодые веб-разработчики не знают ничего, кроме одностраничных приложений и фреймворков, используемых для их создания. «Устаревшая» технология, подходящая только для создания документов со ссылками, текстом и графикой? Ничего подобного! В вашем распоряжении — эффективная технология для построения приложений. Познакомьтесь с новыми инструментами — htmx и Hyperview, которые используют гипермедиа в качестве системной архитектуры. Научитесь строить сложные пользовательские интерфейсы с использованием гипермедиа как базовой технологии: на базе htmx для веб-приложений и на базе Hyperview для мобильных. А затем исследуйте прикладные современные подходы к построению веб-приложений, в которых эта архитектура используется. Гипермедиа-управляемая архитектура подойдет не для каждого приложения, но повышенная гибкость и простота станут огромным преимуществом. Даже если этот подход не улучшит вашу программу, вам стоит понять его суть, сильные и слабые стороны и отличия от традиционно применяемой методики. Веб-среда росла быстрее, чем любая другая распределенная система в истории, и веб-разработчики должны уметь использовать сильные стороны базовых технологий, которые сделали возможным этот рост.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 433
Veröffentlichungsjahr: 2024
Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:
Переводчики Е. Матвеев, Е. Матвеев
Карсон Гросс, Адам Степински, Денис Акшимшек
Hypermedia-разработка. htmx и Hyperview. — СПб.: Питер, 2024.
ISBN 978-5-4461-4096-1
© ООО Издательство "Питер", 2024
Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.
Карсон Гросс — сеньор-разработчик с богатым 30-летним опытом создания как фронтенд-, так и бэкенд-приложений. Сооснователь и технический директор компании LeadDyno. Читает курсы в Университете Монтаны (MSU, Montana State University). Главная сфера интересов — языки программирования и веб-разработка на основе технологий гипермедиа.
Адам Степински — директор по инженерным вопросам в компании Instawork. У него более 15 лет опыта разработки и масштабирования технологических платформ в различных компаниях, от стартапов до Google. Адам — создатель Hyperview, мобильной системы гипермедиа.
Денис Акшимшек — инженер-разработчик, увлекающийся гипермедиа и вопросами доступности. Работал в компаниях Rebase Ventures (Великобритания), Big Sky Software (США) и Commspace (ЮАР), где создавал фулстек-приложения, веб-сайты и скрипты.
Ваши замечания, предложения, вопросы отправляйте по адресу [email protected] (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.
Эта книга посвящена построению приложений с использованием систем гипермедиа. На первый взгляд выражение «система гипермедиа» (Hypermedia system) выглядит немного странно: как гипермедиа может быть системой? Разве это не обычный механизм связывания документов?
Как HTML для Всемирной паутины?
Что вообще означает система гипермедиа?
Да, HTML относится к механизмам гипермедиа. Однако в основе Всемирной паутины лежит не только HTML: протокол HTTP (Hyper Text Transfer Protocol) используется для передачи HTML от серверов к клиентам, и с ним связаны многие технические подробности и функции: кэширование, заголовки, коды ответа и т.д.
И конечно, существуют серверы гипермедиа, которые предоставляют клиентам APIгипермедиа (да, API) по сети.
Наконец, нельзя забывать о крайне важном клиенте гипермедиа: программном клиенте, который способен выводить понятный человеку гипермедийный ответ, чтобы человек мог взаимодействовать c удаленной системой. Несомненно, самыми широко известными и часто используемыми клиентами гипермедиа являются веб-браузеры.
Пожалуй, веб-браузеры — самые сложные программы, которыми мы пользуемся. Они не только поддерживают HTML, CSS и многие другие форматы файлов, но и предоставляют исполнительную и программную среду JavaScript — настолько мощную, что веб-разработчики могут создавать в ней целые приложения, почти не уступающие по сложности толстым клиентам (то есть нативным приложениям).
Исполнительная среда JavaScript настолько мощная, что многие разработчики в наши дни игнорируют гипермедийные возможности браузера, предпочитая строить веб-приложения полностью на JavaScript. Такие приложения часто называют одностраничными приложениями, или SPA (Single Page Applications). Вместо того чтобы переходить между страницами, эти веб-приложения используют JavaScript для прямого обновления пользовательского интерфейса. Взаимодействие с сервером в этих приложениях обычно осуществляется с помощью вызовов JSON API через AJAX. А для обновления пользовательского интерфейса часто применяются интерфейсные библиотеки JavaScript в «реактивном» стиле.
В таких приложениях HTML становится довольно громоздким языком описания графического интерфейса, который используется просто потому, что «исторически» находится под рукой (точнее, в браузере).
Приложения, созданные в этом стиле, не являются гипермедиа-управляемыми; они не используют преимущества нижележащей гипермедиа-системы веб-технологий.
Чтобы объяснить, как выглядит гипермедиа-управляемое приложение, и сравнить его с популярным в наше время SPA-подходом, сначала необходимо исследовать всю гипермедиа-систему интернета, не ограничиваясь HTML. Необходимо рассмотреть сетевую архитектуру интернета, включая то, как веб-серверы предоставляют API гипермедиа и как эффективно использовать средства гипермедиа, доступные в гипермедийном клиенте (например, браузере).
Все вышеперечисленные компоненты важны для построения эффективных гипермедиа-управляемых приложений и составляют в совокупности систему, которая и делает гипермедиа столь мощной архитектурой.
Чтобы понять, что представляет собой система гипермедиа, сначала разберем каноническую систему: Всемирную паутину. Рой Филдинг (Roy Fielding) — инженер, который помогал создавать спецификации и строить реализации многих первых составляющих веб-среды, — ввел термин REST (REpresentational State Transfer), то есть «передача состояния представления». В своей диссертации он описал REST как сетевую архитектуру, которая противопоставлялась более ранним способам построения распределенных программных систем.
Мы определяем систему гипермедиа как RESTful-систему, то есть систему, которая соответствует принципам сетевой архитектуры REST в исходном понимании этого термина Филдингом.
К сожалению, в наши дни термин REST обычно ассоциируется с JSON API, так как именно в этом контексте он обычно применяется в отрасли. Такое использование термина REST не совсем корректно, потому что JSON не является естественным гипермедийным языком из-за отсутствия средств управления гипермедиа. Обмен гипермедийной информацией — явное условие того, чтобы система могла считаться RESTful. Как мы пришли к этой ситуации со столь некорректным использованием термина REST? Это долгая история, и подробнее мы поговорим об этом позже. А пока, если вам кажется, что REST обязательно подразумевает JSON, попробуйте отойти от этого представления на время чтения книги и взглянуть на концепцию по-новому.
Важно понимать, что в своей диссертации Филдинг описывал Всемирную паутину в том состоянии, в каком она существовала в конце 1990-х годов. Тогда она просто состояла из веб-браузеров, обменивавшихся гипермедиа. Эта система с ее простыми ссылками и формами была тем, что Филдинг называл RESTful.
До того, как JSON API станет популярным инструментом веб-разработки, оставалось еще десять лет; концепция REST относилась к гипермедиа и версии 1.0 веб-среды.
В этой книге мы взглянем на гипермедиа как на системную архитектуру, а затем исследуем некоторые практические, современные подходы к построению веб-приложений, в которых эта архитектура используется. Приложения, построенные в этом стиле, будем называть гипермедиа-управляемыми приложениями, или HDA (Hypermedia-Driven Applications); мы сравним их с популярным стилем, применяемым в наши дни, — одностраничными приложениями (SPA).
Гипермедиа-управляемые приложения строятся на основе системы гипермедиа, которая соблюдает гипермедийную функциональность нижележащей системы и использует ее.
Цель этой книги — понятно объяснить читателю, чем архитектура RESTful-системы гипермедиа отличается от других систем «клиент — сервер» и какие сильные (и слабые) стороны присущи гипермедийным решениям. Кроме того, мы надеемся убедить читателя, что архитектура гипермедиа актуальна в современной веб-разработке.
Мы рассмотрим инструменты, которые помогут оценить требования к приложениям и ответить на вопрос: «Можно ли построить это приложение как гипермедиа-управляемое?»
Надеемся, вы ответите «да» применительно ко многим приложениям.
Книга включает три части:
• Введение в гипермедиа, в котором особое внимание уделяется темам HTML и HTTP. Обзор основных концепций гипермедиа завершается созданием простого приложения для управления контактами «в стиле Web 1.0», Contact.app.
• Затем вы научитесь использовать htmx1 — гипермедиа-ориентированную библиотеку JavaScript, разработанную авторами этой книги, и с ее помощью улучшите приложение Contact.app. Благодаря htmx мы добьемся уровня интерактивности, который многие разработчики посчитали бы невозможным без большой, сложной интерфейсной библиотеки, такой как React. С htmx мы сделаем это, используя гипермедиа в качестве системной архитектуры.
• Наконец, мы рассмотрим Hyperview — совершенно особую мобильную систему гипермедиа, которая имеет отношение к веб-технологиям, но отличается от них. Эту систему создал один из авторов этой книги, Адам Степински. Она поддерживает специфические мобильные возможности за счет предоставления не только мобильных гипермедиа-технологий, но и мобильного гипермедиа-клиента. Эти новые компоненты в сочетании с любым сервером HTTP позволяют создавать мобильные гипермедиа-управляемые приложения.
Заметим, что каждую часть книги можно изучать отдельно от других. Если вы уже хорошо разбираетесь в теме гипермедиа и знаете, как работают базовые приложения Web 1.0, вы можете переходить сразу к части II с описанием htmx и построения современных веб-приложений на основе технологий гипермедиа. Точно так же, если вы уже разбираетесь в htmx и хотите глубже изучить новое направление мобильных гипермедиа-технологий, можете переходить прямо к части, посвященной Hyperview.
Тем не менее книга создавалась с расчетом на последовательное изучение, и в разделах, посвященных htmx и Hyperview, используется приложение Web 1.0, описанное в конце части I.
Более того, даже если вы хорошо разбираетесь во всех концепциях гипермедиа и деталях HTML и HTTP, мы рекомендуем хотя бы бегло просмотреть несколько первых глав, чтобы освежить эти темы в памяти.
В наши дни гипермедиа нечасто является предметом обсуждения. Даже многие опытные программисты, выросшие вместе с Всемирной паутиной в конце 1990-х и начале 2000-х годов, не уделяли идеям гипермедиа особого внимания. Некоторые молодые веб-разработчики не знают ничего, кроме одностраничных приложений и фреймворков, используемых для их создания.
В частности, многие начинали свою карьеру с построения приложений React.js, взаимодействующих с сервером Node через JSON API; некоторые разработчики вообще никогда не рассматривали гипермедиа как систему.
Это весьма печальный факт — и откровенно говоря, не в последнюю очередь дело в неумении лидеров сообщества веб-разработки доносить информацию и объяснять преимущества гипермедийного подхода.
Идея гипермедиа была просто превосходной! И такой осталась!
К концу этой книги вы будете владеть инструментами и языком, который позволит вам эффективно применять эту отличную идею в своих приложениях. Кроме того, вы сможете распространить принципы и концепции систем гипермедиа в широком сообществе веб-разработчиков.
Гипермедиа может конкурировать с другими технологиями, гипермедиа может побеждать, архитектура гипермедиа сможет занять место одностраничных приложений — но только если умные люди (как вы) будут знать об этой концепции, применять ее при построении приложений и рассказывать о ней миру.
Будущее не определено. Нет судьбы, кроме той, что мы творим сами.
Кайл Риз, «Терминатор 2: Судный день»
Очевидно, HTML играет центральную роль в истории, которую мы рассказываем. В конце каждой главы мы будем делиться тем, что узнали о написании HTML для гипермедиа-управляемых веб-приложений.
Для начала вспомним, что веб-приложения — не изолированные системы. Мы пишем HTML не только для конкретного приложения, но и для того, чтобы оно могло взаимодействовать с другими компонентами веб-инфраструктуры. Если мы будем писать код с прицелом на создание системы гипермедиа, то сможем более эффективно пользоваться всеми возможностями, доступными в Сети.
Язык HTML хорошо сочетается с гипермедиа, когда разметка пишется для всех составляющих системы гипермедиа. Он передает состояние приложения пользователям, просматривающим сайты в браузере, а также тем, кто слушает экранный диктор, устно описывающий содержимое сайта. Он передает информацию о предназначении сайтов поисковым системам, которые собирают данные на программном уровне. Кроме того, он информирует о своем поведении других разработчиков максимально ясным способом.
Нет, хорошая разметка HTML не решит всех проблем. Мантра о том, что язык HTML «доступен по умолчанию», только мешает. Отказываясь от других технологий (например, JavaScript), мы лишимся важных возможностей. А чтобы убедиться, что все работает так, как задумано, все равно придется тестировать — везде и много.
Тем не менее хорошая разметка HTML послужит тому, что браузеры выполнят бˆольшую часть работы за нас.
1 https://htmx.org/
В наши дни технология гипермедиа стала универсальной и почти так же распространена, как электричество.
Миллиарды людей ежедневно используют системы на основе гипермедиа, в основном на уровне взаимодействия с языком гипертекстовой разметки HTML (Hypertext Markup Language), передаваемом по протоколу HTTP (Hypertext Transfer Protocol); для этого используется веб-браузер, подключенный к Сети.
Такие системы используются для получения новостей, общения с друзьями, покупок в интернете, игр, отправки электронной почты и т.д. Разнообразие и количество онлайн-сервисов, предоставляемых через гипермедиа, потрясает воображение.
Тем не менее, несмотря на такую распространенность, тема гипермедиа сама по себе остается на удивление малоизученной; в основном ею занимаются специалисты. Да, можно без труда найти множество пособий о том, как писать HTML, создавать ссылки и формы и т.д. Однако HTML очень редко рассматривается как технология гипермедиа, а в более широком смысле и как комплекс систем гипермедиа.
Ситуация заметно отличается от той, что была на заре веб-разработки, когда такие концепции, как REST (Representational State Transfer) или HATEOAS (Hypermedia As The Engine of Application State, «гипермедиа как ядро состояния приложения»), часто обсуждались, уточнялись и вызывали споры между веб-разработчиками.
Как ни печально, сегодня многие ругают самый популярный язык гипермедиа — HTML: это громоздкий, устаревший язык разметки, который приходится применять в пользовательских интерфейсах веб-приложений, уже почти полностью создаваемых на JavaScript. Так получилось, что HTML присутствует в браузере и мы вынуждены с ним работать.
Такой подход удручает, и мы надеемся убедить вас в том, что гипермедиа — не просто устаревшая технология, которую приходится принимать и использовать. Мы хотим показать, что гипермедиа — невероятно революционный, простой и гибкий способ построения надежных приложений: гипермедиа-управляемых приложений.
Хочется верить, что к концу этой книги вы, как и мы, почувствуете, что гипермедиа может стать хорошим выбором архитектуры приложения, которое вы планируете разрабатывать. Вариант гипермедиа-управляемого приложения на основе системыгипермедиа (такой, как веб) вполне жизнеспособен; более того, нередко это отличное решение для современного веб-приложения.
(И как будет показано в части, посвященной Hyperview, не только для веб-приложения.)
Гипертекст — новая форма письма, выводимая на экран компьютера, которая ветвится или выполняет действие по запросу читателя. Гипертекст является нелинейной формой письма; он приносит практическую пользу только при выводе на экран.
Тед Нельсон, https://archive.org/details/SelectedPapers1977/page/n7/mode/2up
Начнем с самого начала: что такое гипермедиа?
Гипермедиа — информационная среда (например, текст) с возможностью нелинейного перехода из одной своей точки в другую по встроенным гиперссылкам. Префикс «гипер-» происходит от греческого префикса «ὑπερ-», означающего «за пределами» или «сверх-». Он указывает, что гипермедиа выходит за рамки обычных, пассивно потребляемых информационных сред, таких как журналы или газеты.
Гиперссылки — классический пример того, что называется элементом управления гипермедиа (hypermedia control).
Элемент управления гипермедиа — это элемент гипермедиа, описывающий некоторое взаимодействие (или управляющий этим взаимодействием), часто с удаленным сервером. Информация об этом взаимодействии напрямую и полностью кодируется внутри самого элемента.
Элементы управления — то, что отличает гипермедиа от других видов информационных средств.
Возможно, вам более знаком термин «гипертекст»; приведенное выше определение взято со страницы в «Википедии», посвященной гипертексту. Гипертекст составляет подкатегорию гипермедиа, и бо́льшая часть этой книги будет посвящена тому, как строить современные приложения на основе гипертекста, например HTML (Hypertext Markup Language) или HXML (гипертекста, используемого мобильной гипермедиа-системой Hyperview).
Гипертекст, как HTML, работает в сочетании с другими технологиями, необходимыми для функционирования всей системы гипермедиа: сетевыми протоколами (такими, как HTTP), другими типами информационных сред (например, графикой или видео), серверами гипермедиа (то есть серверами, предоставляющими API гипермедиа), полнофункциональными клиентами гипермедиа (например, веб-браузерами) и т.д.
По этой причине для описания базовой архитектуры приложений с применением гипертекста мы предпочитаем более широкий термин сиcтемы гипермедиа, чтобы подчеркнуть роль системной архитектуры в конкретной используемой разновидности гипермедиа.
Именно архитектура системы гипермедиа в целом не пользуется должным вниманием и игнорируется многими современными веб-разработчиками.
Как возникла идея гипермедиа?
Хотя у современной концепции гипертекста и более общей концепции гипермедиа было много предшественников, отправной точкой для формирования современных представлений о гипермедиа многие считают статью Ванневара Буша (Vannevar Bush) «As We May Think», вышедшую в 1945 году в журнале «Atlantic».
В этой статье Буш описал устройство, которое он назвал Memex. Это устройство, использовавшее сложную механическую систему катушек и микропленок в сочетании с системой кодирования, давало бы возможность пользователю переходить между взаимосвязанными кадрами контента. Устройство Memex так никогда и не было создано, но его идея послужила вдохновением для последующей проработки концепции гипермедиа.
Термины «гипертекст» и «гипермедиа» были введены в 1963 году Тедом Нельсоном (Ted Nelson), который работал над системой редактирования гипертекста в Университете Брауна, а позднее создал FRESS (File Retrieval and Editing System) — невероятно передовую для своего времени систему гипермедиа. (Не исключено, что это была первая цифровая система с возможностью «отмены» (undo).)
Пока Нельсон работал над своими идеями, Дуглас Энгельбарт (Douglas Engelbart) трудился в Стэнфордском исследовательском институте, пытаясь воплотить в реальность устройство Memex Ванневара Буша. В 1968 году Энгельбарт провел «демонстрацию века» в Сан-Франциско, штат Калифорния.
Энгельбарт продемонстрировал ряд невероятных технологических достижений:
• дистанционное редактирование текста совместно с коллегами в Менло-Парке;
• видео- и аудиочат;
• интегрированную систему окон с возможностью изменения размеров окон и других параметров;
• гипертекст, в котором по щелчку на подчеркнутом фрагменте происходит переход к новому контенту.
Несмотря на бурные овации потрясенной после выступления аудитории, прошли десятилетия, прежде чем продемонстрированные Энгельбартом технологии получили массовое распространение.
В 1990 году Тим Бернерс-Ли (Tim Berners-Lee), работавший в CERN, опубликовал первый веб-сайт. Он работал над идеей гипертекста около 10 лет. Наконец, в отчаянии от того факта, что ученым так трудно делиться результатами своих исследований, он нашел подходящий момент и организационную поддержку для создания Всемирной паутины:
Создание Всемирной паутины в действительности было актом отчаяния, потому что во время моей работы в CERN ситуация была очень сложной. Многие технологии, задействованные во Всемирной паутине (гипертекст, интернет, многошрифтовые текстовые объекты), уже были спроектированы. Мне оставалось лишь объединить их. Это было обобщением, переходом на более высокий уровень абстракции, попыткой рассматривать все системы документации как части более крупной воображаемой системы документации.
Тим Бернерс-Ли https://britishheritage.org/tim-berners-lee-the-world-wide-web
К 1994 году его творение стало развиваться настолько быстро, что Бернерс-Ли основал W3C — группу компаний и исследователей, работавших над улучшением Паутины. Все стандарты, созданные W3C, не требовали лицензионных отчислений. Любой желающий мог адаптировать и реализовать их, что привело к укреплению открытой, ориентированной на сотрудничество природы Всемирной паутины.
В 2000 году Рой Филдинг, тогда работавший в Калифорнийском университете в Ирвайне, опубликовал во Всемирной паутине свою судьбоносную диссертацию «Architectural Styles and the Design of Network-based Software Architectures» («Архитектурные стили и дизайн программных архитектур сетевой среды»). Филдинг работал над HTTP-сервером с открытым исходным кодом Apache и в своей работе описывал то, что считал новой особой сетевой архитектурой, появившейся в ранней версии Паутины.
Филдинг работал над первыми спецификациями HTTP. В своей статье для определения сетевой модели гипермедиа он использовал термин REST (REpresentational State Transfer).
Работа Филдинга стала опорой для первых веб-разработчиков, получивших в свое распоряжение язык для обсуждения новой технической среды, в которой они строили приложения.
Мы подробно обсудим ключевые идеи Филдинга в главе 2, а заодно попытаемся навести порядок с определениями REST, HATEOAS и гипермедиа.
В начале была гиперссылка, и гиперссылка была с веб-средой, и гиперссылка была веб-средой. И это было хорошо.
Rescuing REST From the API Winter. https://intercoolerjs.org/2016/01/18/rescuing-rest.html
HTML, над которым работали Бернерс-Ли, Филдинг и многие другие, создавался вокруг гипермедиа. Изначально разметка HTML представляла собой гипермедиа-текст, предназначенный только для чтения и используемый для публикации академических документов. Эти документы связывались при помощи якорных тегов, которые создавали между ними гиперссылки. При помощи этих ссылок пользователи могли быстро перемещаться от одного документа к другому.
В спецификации HTML 2.0 появилось понятие тега form, присоединившегося к якорному тегу (то есть гиперссылке) как второй элемент управления. Введение тега form открыло возможность построения приложений в веб-среде, так как оно предоставляло механизм обновления ресурсов, а не только их чтения.
В этот момент Всемирная паутина из интересной документоориентированной системы превратилась в перспективную архитектуру приложений.
В наши дни HTML является самой широко используемой технологией гипермедиа. Естественно, предполагается, что наш читатель достаточно хорошо знаком с ней. Вам не нужно быть экспертом в области HTML (или CSS), чтобы понять приведенный в книге код, но чем лучше вы разбираетесь в основных тегах и концепциях HTML, тем больше пользы принесет вам книга.
Рассмотрим два определяющих гипермедиа-элемента (элемента управления) HTML — якорный тег и тег формы — более подробно.
Якорные теги встречаются настолько часто, что кажутся набившими оскомину. И все же стоит рассмотреть механику работы гиперссылок, чтобы настроиться на более глубокое понимание гипермедиа.
Возьмем простой якорный тег, встроенный в документ HTML.
Листинг 1. Простая гиперссылка
<a href="https://hypermedia.systems/">
Системы гипермедиа
</a>
Якорный тег состоит из собственно тега <a></a>, а также атрибутов и контента внутри тега. Особый интерес представляет атрибут href, который задает гипертекстовую ссылку на другой документ или фрагмент документа. Именно этот атрибут превращает якорный тег в элемент гипермедиа.
Типичный браузер будет интерпретировать этот якорный тег следующим образом:
• Вывести текст «Системы гипермедиа» в такой форме, чтобы пользователь видел, что на нем можно щелкнуть.
• Когда пользователь щелкает на этот текст, выдать запрос HTTPGET к URL https://hypermedia.systems/.
• Принять HTML-контент из тела ответа HTTP на этот запрос и заменить весь экран в браузере новым документом, с обновлением адресной строки новым URL-адресом.
Якорные ссылки обеспечивают основной механизм перемещения в современной веб-среде — переход по ссылке от документа к документу или от ресурса к ресурсу.
Схематично взаимодействие пользователя с якорным тегом/гиперссылкой выглядит так:
Рис. 1. Запрос HTTP GET в действии
При щелчке на ссылке браузер (или, как иногда говорят, клиент гипермедиа) инициирует GET-запрос HTTP к URL-адресу, закодированному в атрибуте href ссылки.
Обратите внимание, что запрос HTTP включает дополнительные данные (метаданные). Они описывают, что именно браузеру нужно получить от сервера, в форме заголовков. Эти заголовки и HTTP более подробно рассматриваются в главе 2.
Затем с серверагипермедиа поступает гипермедийный ответ на запрос — разметка HTML — для новой страницы. На первый взгляд этот момент может показаться незначащим и очевидным, но это исключительно важный признак системы гипермедиа, действительно отвечающей условиям REST: клиент и сервер должны взаимодействовать через гипермедиа!
Якорные теги обеспечивают навигацию между документами или ресурсами, но не позволяют обновлять эти ресурсы. За эту функциональность отвечает тег form.
Простой пример формы HTML:
Листинг 2. Простая форма
<form action="/signup" method="post">
<input type="text" name="email" placeholder="Укажите адрес электронной почты,
чтобы зарегистрироваться..."/>
<button>Регистрация</button>
</form>
Как и якорный тег, тег формы состоит из собственно тега <form></form>, а также атрибутов и контента внутри тега. Обратите внимание: у тега формы нет атрибута href, но есть атрибут action, указывающий, куда следует направить запрос HTTP. Кроме того, он содержит атрибут method, который точно указывает, какой «метод» HTTP должен использоваться. В приведенном примере форма дает команду браузеру выдать запрос POST.
В отличие от якорных тегов, контент и теги внутри формы могут влиять на гипермедиа-взаимодействие между формой и сервером. Значения тегов input и других тегов (например, select) при отправке данных формы будут включены в запрос HTTP как параметры URL в случае GET и как часть тела запроса в случае POST. В отличие от якорного тега, это позволяет форме включать в запрос произвольный объем информации, полученной от пользователя.
Типичный браузер будет интерпретировать этот тег формы и его содержимое примерно следующим образом:
• Вывести текстовое поле ввода и кнопку «Регистрация» для пользователя.
• Когда пользователь отправит данные формы, щелкнув на кнопке «Регистрация» или нажав клавишу Enter, пока элемент input обладает фокусом, направить запрос HTTP POST по пути /signup «текущего» сервера.
• Принять HTML-контент из тела ответа HTTP и заменить весь экран в браузере новым документом, с обновлением адресной строки новым URL-адресом.
Этот механизм позволяет пользователю выдавать запросы на обновлениесостояния ресурсов на сервере. Заметим, что, несмотря на новый тип запроса, весь обмен данными между клиентом и сервером все еще происходит исключительно через гипермедиа.
Именно тег формы делает возможным существование гипермедиа-управляемых приложений.
Вероятно, опытный веб-разработчик заметит, что мы опустили некоторые подробности и трудные случаи. Например, ответ на отправку формы часто перенаправляет клиента на другой URL-адрес.
Это правда, и мы еще займемся техническими подробностями форм в следующих главах, а пока и этого простого примера будет достаточно для демонстрации базового механизма обновления состояния системы исключительно через гипермедиа.
Диаграмма взаимодействия выглядит так:
Рис. 2. Запрос HTTP POST в действии
Как человеку, интересующемуся веб-разработкой, вам, вероятно, уже знакомы приведенные выше диаграммы и рассуждения. Возможно, кому-то этот материал даже покажется скучным. Но сделайте шаг назад и обратите внимание на тот факт, что этими двумя элементами гипермедиа — якорями и формами — ограничиваются все собственные возможности базового HTML для взаимодействия пользователя с сервером.
Всего два тега!
Тем не менее они обеспечили Всемирной паутине на заре ее развития рост с экспоненциальной скоростью и возможность предоставлять невероятно огромный объем динамической онлайн-функциональности миллиардам людей.
Это убедительное доказательство мощи гипермедиа. Даже сегодня, когда в веб-разработке все чаще на ведущие позиции выходят большие JavaScript-ориентированные интерфейсные фреймворки, многие предпочитают использовать для достижения своих целей простой базовый HTML, и нередко результат их полностью устраивает.
Эти два тега наделяют HTML колоссальной выразительностью.
Итак, ссылки и формы — два основных механизма гипермедиа, предназначенные для взаимодействия с сервером и доступные в HTML.
Теперь рассмотрим другой подход: взаимодействие с сервером посредством выдачи запроса HTTP через JavaScript. Для этого мы будем использовать fetch()2 — популярный API для выдачи запросов «асинхронного JavaScript и XML», или запросов AJAX (Asynchronous JavaScript and XML), доступный во всех современных браузерах.
Листинг 3. JavaScript
<button onclick="fetch('/api/v1/contacts/1') ❶
.then(response => response.json()) ❷
.then(data => updateUI(data))"> ❸
Fetch Contact
</button>
❶ Выдача запроса.
❷ Преобразование ответа в объект JavaScript.
❸ Вызов функции updateUI() с объектом.
Кнопка имеет атрибут onclick, в котором хранится код JavaScript, выполняемый при щелчке по ней.
JavaScript выдает запрос AJAX HTTP GET к пути /api/v1/contacts/1 с использованием fetch(). Запрос AJAX похож на «обычный» запрос HTTP, но он выдается браузером скрыто. Пользователь не видит индикатор запроса от браузера, как в случае с обычными ссылками и формами. Кроме того, в отличие от запросов, выдаваемых этими элементами управления, за обработку ответа от сервера отвечает код JavaScript.
Хотя в акроним AJAX входит XML, в наши дни ответ HTTP на такой запрос почти наверняка будет закодирован в формате JSON (JavaScript Object Notation), а не в XML.
Ответ HTTP на этот запрос может выглядеть примерно так:
Листинг 4. JSON
{ ❶
"id": 42, ❷
"email" : "[email protected]" ❸
}
❶ Начало объекта JSON.
❷ Свойство — в данном случае с именем id и значением 42.
❸ Другое свойство — адрес электронной почты контакта с этим id.
Приведенный выше код JavaScript преобразует текст JSON, полученный от сервера, в объект JavaScript; для этого текст передается в вызове метода json(). Далее новый объект JavaScript передается методу updateUI().
Метод updateUI() отвечает за обновление пользовательского интерфейса на основании данных, закодированных в объекте JavaScript, — возможно, c выводом данных контакта в разметке HTML, генерируемой клиентским шаблоном в приложении JavaScript.
Подробности того, что делает функция updateUI(), нам неважны.
А что важно и что является критической особенностью взаимодействий с сервером на основе JSON — то, что в них не используются гипермедиа. JSON API не возвращает гипермедийный ответ. В нем нет гиперссылок или других элементов гипермедиа. Здесь JSON API скорее является API данных.
Так как ответ закодирован в формате JSON, а не в формате гипермедиа, методу JavaScript updateUI() нужна информация, как преобразовать эти контактные данные в HTML.
В частности, коду updateUI() необходимы сведения о внутренней структуре и смысле данных. Он должен знать:
• точную структуру и имена полей в объекте данных JSON;
• какими отношениями они связаны;
• как обновить локальные данные, которым соответствуют эти новые данные;
• как отобразить эти данные в браузере;
• какие дополнительные действия / конечные точки API могут вызываться с этими данными.
Вкратце, логика updateUI() должна обладать полной информацией о конечной точке API, имеющей путь /api/v1/contact/1, причем эта информация должна предоставляться сторонним источником не внутри самого ответа. В результате между кодом updateUI() и API возникают особые отношения, называемые сильной связанностью (tight coupling): если формат ответа JSON изменится, то код updateUI() почти наверняка тоже придется изменять.
Хотя приведенный фрагмент кода JavaScript выглядит очень скромно, это органическое начало целой большой концепции создания веб-приложений. С него начинаются одностраничные приложения (Single Page Application, SPA). Веб-приложение уже не осуществляет навигацию между страницами с использованием гипермедийных элементов управления, как это было со ссылками и формами.
Вместо этого приложение обменивается обычными данными с сервером, а затем обновляет контент в пределах одной страницы.
Когда такая стратегия или архитектура принимается для всего приложения, все фактически происходит на одной странице и приложение становится «одностраничным».
Архитектура одностраничных приложений стала чрезвычайно популярна и в последнее десятилетие доминирует при построении веб-приложений. Об этом говорят высокий уровень внимания отрасли к этой архитектуре и частота ее обсуждений.
В наши дни в подавляющем большинстве одностраничных приложений для управления пользовательским интерфейсом применяются намного более сложные фреймворки, чем показано в этом простом примере. Такие популярные библиотеки, как React, Angular, Vue.js и т.д., стали распространенным — и можно сказать, стандартным — способом построения веб-приложений.
С такими сложными фреймворками разработчики обычно применяют более тщательно проработанную модель на стороне клиента, а именно объекты JavaScript, хранимые локально в памяти браузера и представляющие «модель» или «предметную область» приложения. Эти объекты JavaScript обновляются кодом JavaScript, а фреймворк «реагирует» на эти изменения обновлением пользовательского интерфейса.
Когда пользовательский интерфейс (UI) обновляется пользователем, эти изменения также распространяются в объекты модели, устанавливая «двусторонний» механизм связывания: модель может обновить пользовательский интерфейс, а пользовательский интерфейс может обновить модель.
Это намного более сложный подход к веб-клиенту, чем гипермедиа. Обычно он почти полностью упраздняет нижележащую инфраструктуру гипермедиа, доступную в браузере.
HTML все еще используется для построения пользовательских интерфейсов, но гипермедийный аспект двух основных элементов гипермедиа, якорей и форм, остается незадействованным. Ни один из этих тегов не взаимодействует с сервером через нативный механизм гипермедиа. Вместо этого они становятся элементами пользовательского интерфейса, которые управляют локальными взаимодействиями с моделью предметной области в памяти через JavaScript; далее они синхронизируются с сервером с использованием простых данных JSON API.
Итак, как в приведенном выше примере с простой кнопкой, одностраничные приложения работают в обход архитектуры гипермедиа. При этом они отказываются от преимуществ существующей RESTful-архитектуры веб-среды и встроенной функциональности нативных элементов гипермедиа в пользу поведения, управляемого JavaScript.
SPA-приложения представляют собой нечто намного большее, чем толстые клиенты, то есть приложения «клиент — сервер» 1980-х — архитектура, которая была популярна до появления Всемирной паутины и реакцией на которую во многих отношениях и стало возникновение Всемирной паутины.
Конечно, такой подход не обязательно ошибочен: в некоторых случаях толстый клиент — вполне подходящий выбор для приложения. Однако стоит задуматься, почему веб-разработчики так часто выбирают этот вариант, не учитывая альтернативы, и нет ли причин выбрать другой подход.
Одностраничные приложения React с рендерингом на стороне сервера становятся своеобразной нормой веб-разработки. Два ключевых элемента этой архитектуры выглядят примерно так:
1. Основной пользовательский интерфейс строится и обновляется в JavaScript с применением React или похожей библиотеки.
2. Серверная часть представлена API, к которому приложение обращается с запросами.
Эта идея действительно захватила интернет. Все началось с нескольких крупных популярных сайтов и дошло до маркетинговых сайтов и блогов.
Том Макрайт (Tom MacWright), https://macwright.com/2020/05/10/spa-fatigue.html
Схема одностраничных приложений на основе JavaScript захватила веб-разработку, и если бы кому-то предложили назвать единственную причину ее бешеного успеха, он бы выбрал следующую: одностраничные приложения обеспечивают намного больший уровень интерактивности и иммерсивности, чем старые громоздкие приложения Web 1.0 на основе гипермедиа. SPA-приложения обладают целым рядом преимуществ: плавным обновлением элементов, встроенных в страницу, без перезагрузки всего документа; использованием переходов CSS для создания привлекательных визуальных эффектов; возможностью хука произвольных событий (например, перемещений мыши).
Все эти возможности обеспечивают приложениям на основе JavaScript огромное преимущество при построении сложных пользовательских интерфейсов.
С учетом популярности, мощи и успеха этого современного подхода к созданию веб-приложений зачем кому-то использовать старый, громоздкий и менее популярный подход, такой как гипермедиа?
Хорошо, что вы спросили!
Оказывается, архитектура гипермедиа, даже в своей исходной форме Web 1.0, обладает рядом преимуществ по сравнению со связкой «SPA + JSON Data API». Вот три основных:
• Это чрезвычайно простой подход к построению веб-приложений.
• Он очень хорошо переносит изменения контента и API. Более того, он от них выигрывает!
• В нем используются проверенные, надежные механизмы веб-браузеров, такие как кэширование.
В частности, первые два преимущества решают серьезные проблемы современной веб-разработки:
• Одностраничная инфраструктура стала в высшей степени сложной, для управления ею часто требуются усилия всей команды.
• Пересмотр JSON API — постоянные изменения, вносимые в JSON API для поддержки потребностей приложения, — стал болевой точкой для многих команд разработки.
Наличие этих проблем в сочетании с другими проблемами (например, пересмотром библиотеки JavaScript) привело к явлению, известному как «усталость от JavaScript». Под ним понимается общее нежелание продираться через все препоны, чтобы хоть что-нибудь сделать в современных веб-приложениях.
Мы уверены, что архитектура гипермедиа способна излечить многие команды и отдельных разработчиков от «усталости от JavaScript».
Но если концепция гипермедиа настолько хороша и если она решает столько проблем, преследующих отрасль веб-разработки, почему она оказалась на обочине? В конце концов, она появилась раньше других. Почему веб-разработчики ей не следовали?
Существуют две основные причины, по которым решения гипермедиа не пользуются особой популярностью у веб-разработчиков.
Первая: выразительность HTML как гипермедиа практически не изменилась (или вообще не изменилась) с момента возникновения HTML 2.0 в середине 1990-х. Конечно, в HTML появилось много новых функций, но почти три десятилетия мы не видели никаких действительно новых способов взаимодействия с сервером из HTML.
Из элементов гипермедиа у разработчиков HTML по-прежнему только якорные теги и формы, и эти элементы управления могут выдавать только запросы GET и POST.
Необъяснимое отсутствие прогресса в HTML немедленно ведет ко второй и, пожалуй, более практической причине, по которой концепция «HTML как гипермедиа» не прижилась: пока интерактивность и выразительность HTML оставались на прежнем уровне, потребности веб-пользователей продолжали расти — пользователи ожидали все более и более интерактивных веб-приложений.
Приложения на основе JavaScript в сочетании с JSON API, ориентированными на данные, предложили способ реализации более сложных пользовательских интерфейсов. Именно опыт взаимодействия с пользователем, который можно было обеспечить в JavaScript и которого нельзя было достичь в простом HTML, подтолкнул сообщество веб-разработки к одностраничной архитектуре на основе JavaScript. Сдвиг не был вызван каким-то внутренним превосходством одностраничного приложения как системной архитектуры.
Но события не обязательно должны были развиваться по этому сценарию. В идею гипермедиа не заложено ничего, что помешало бы ей иметь более богатую и выразительную модель интерактивности, чем минимальный HTML. Вместо того чтобы уходить от решений на основе гипермедиа, отрасль могла бы потребовать большей интерактивности от HTML.
Вместо этого стандартом стало создание приложений в стиле толстого клиента для веб-браузеров — понятный переход к более знакомой модели для построения полнофункциональных приложений.
Конечно, не все отказались от идеи гипермедиа. Известны героические попытки продолжить продвижение гипермедиа за рамками HTML, такие как HyTime, VoiceXML и HAL.
Однако язык HTML — наиболее широко используемая среда гипермедиа — перестал развиваться как гипермедиа. Веб-разработка эволюционировала, решая проблемы интерактивности в HTML переходом на модель SPA, основанную на JavaScript, и, в основном непреднамеренно, на совершенно иную системную архитектуру.
Интересно представить, по какому пути мог бы пойти язык HTML. Вместо того чтобы застыть как гипермедийная среда, мог ли HTML продолжить свое развитие? Мог ли он дополняться новыми элементами гипермедиа и расширять выразительность уже существующих? Получилось бы создать современное веб-приложение в исходной гипермедиа-ориентированной RESTful-модели, которая сделала раннюю версию Всемирной паутины столь мощной, гибкой и увлекательной?
Кто-то скажет, что это всего лишь досужие домыслы, но у нас есть хорошие новости: за последнее десятилетие появились неординарные альтернативные интерфейсные библиотеки, которые пытаются вдохнуть новую жизнь в HTML. Как ни парадоксально, эти библиотеки написаны на JavaScript — технологии, заместившей HTML в веб-разработке.
Тем не менее эти библиотеки используют JavaScript не как замену фундаментальной гипермедийной системы веб-среды. JavaScript применяется для дополнения самого языка HTML как платформы гипермедиа.
Эти гипермедиа-ориентированные библиотеки снова делают гипермедиа основополагающей технологией веб-приложений.
В веб-разработке уже давно идут споры между сторонниками одностраничного (SPA) подхода и того, что сейчас называется «многостраничным» подходом, или MPA (Multi-Page Application). MPA — это просто новое обозначение старого способа построения веб-приложений в стиле Web 1.0 с использованием ссылок и форм, размещенных на разных веб-страницах, с отправкой запросов HTTP и получением ответов HTML.
Приложения MPA по своей природе являются гипермедиа-управляемыми; в конце концов, именно их Рой Филдинг описывал в своей диссертации.
Эти приложения кажутся громоздкими, но работают достаточно хорошо. Многие веб-разработчики и команды решают выбрать ограничения простого HTML в пользу простоты и надежности.
Рич Харрис (Rich Harris), создатель Svelte.js (популярной библиотеки SPA) и идейный лидер стороны SPA в этом споре, предложил объединить старый стиль MPA с новым стилем SPA. Харрис называет такой подход к построению веб-приложений «переходным» в том смысле, что он пытается осуществить слияние MPA и SPA в единое целое. (Такое использование термина отчасти напоминает «переходный» стиль в архитектуре, сочетающий традиционные и современные архитектурные стили.)
Термин «переходный» подходит для приложений смешанного стиля. Он обеспечивает разумный компромисс между двумя подходами, позволяя использовать наиболее подходящий вариант в каждом конкретном случае.
Тем не менее такой компромисс все еще остается неудовлетворительным.
Нужно ли включать эти две очень разные архитектурные модели в наши приложения по умолчанию?
Вспомните, что принципиальным моментом выбора между SPA и MPA является опыт взаимодействияс пользователем, или интерактивность приложения. Обычно этот фактор заставляет выбирать тот или иной подход для приложения или (в случае «переходного» приложения) для отдельной функциональности.
Оказывается, выбор гипермедиа-ориентированной библиотеки радикально сокращает разрыв в интерактивности между подходами MPA и SPA. Вы можете использовать подход MPA (то есть гипермедийный подход) для гораздо большей части приложения без ущерба для пользовательского интерфейса. Возможно, вам даже удастся использовать гипермедийный подход для всех потребностей приложения.
Вместо того чтобы создавать приложение SPA с гипермедийными довесками или комбинацию двух подходов, часто можно написать веб-приложение, которое в основном или полностью является гипермедиа-управляемым и которое предоставляет всю интерактивность, необходимую пользователям.
Это позволяет добиться невероятной простоты веб-приложения и создать намного более целостный и понятный продукт. Хотя в каких-то ситуациях все еще может применяться более сложный подход SPA, что мы обсудим позже, переход к решению, ставящему на первое место гипермедийность, и применение гипермедиа-ориентированной библиотеки для расширения возможностей HTML позволяют строить мощные, интерактивные и простые веб-приложения.
К числу таких гипермедиа-ориентированных библиотек относится htmx3. Библиотеке htmx будет посвящена часть II этой книги. Мы покажем, что многие популярные «современные» средства UI, присутствующие в сложных приложениях SPA, можно реализовать на основе модели гипермедиа.
И делать это на удивление просто и интересно.
При построении веб-приложения с htmx термин «многостраничное приложение» применим в общих чертах, но он не характеризует основу архитектуры приложения в полной мере. Как вы вскоре увидите, не обязательно заменять htmx целые страницы; более того, приложение на основе htmx может существовать полностью в пределах одной страницы. Мы не рекомендуем такую практику, но это возможно!
Таким образом, называть веб-приложения, построенные на основе htmx, «многостраничными» не совсем корректно. У старого подхода MPA для приложений Web 1.0 и у приложений на основе новых гипермедиа-ориентированных библиотек есть нечто общее: они используют гипермедиа как базовую технологию и архитектуру.
По этой причине мы будем использовать термин гипермедиа-управляемые приложения, или HDA (Hypermedia-Driven Applications), для описания обеих разновидностей.
Это определение проясняет основное различие между этими двумя подходами, а подход SPA определяет не количество страниц в приложении, а скорее используемую архитектуру системы.
Веб-приложение, использующее гипермедиа и гипермедийный обмен данными в качестве основного механизма взаимодействия с сервером.
Как же выглядит приложение HDA при ближайшем рассмотрении?
Перед вами реализация простой JavaScript-кнопки с использованием htmx.
Листинг 5. Реализация htmx
<button hx-get="/contacts/1" hx-target="#contact-ui"> ❶
Fetch Contact
</button>
❶ Выдает запрос GET к /contacts/1, заменяя contact-ui.
Как и у кнопки на основе JavaScript, у этой кнопки существуют атрибуты. Однако в этом случае не используется (во всяком случае, явно) скриптовый код JavaScript.
Вместо него используются декларативные атрибуты, очень похожие на атрибуты href якорных тегов, или атрибуты action тегов форм. Атрибут hx-get сообщает htmx: «Когда пользователь щелкает на этой кнопке, отправить запрос GET к /contacts/1». Атрибут hx-target сообщает htmx: «Когда будет возвращен ответ, принять полученную разметку HTML и поместить ее в элемент с идентификатором contact-ui».
Здесь мы подходим к сути htmx и тому, как с помощью этой библиотеки строить гипермедиа-управляемые приложения.
Ожидается, что сервер вернет ответ HTTP в формате HTML, а не JSON.
Ответ HTTP на этот запрос под управлением htmx может выглядеть примерно так:
Листинг 6. JSON
<details>
<div>
Contact: HTML Example
</div>
<div>
<a href="mailto:[email protected]">Email</a>
</div>
</details>
Этот маленький фрагмент HTML будет помещен в элемент DOM с идентификатором contact-ui.
Таким образом, кнопка на основе htmx обменивается с сервером данными гипермедиа (как мог бы делать якорный тег или тег формы), и следовательно, взаимодействие ведется в соответствии с базовой гипермедиа-моделью веб-среды. Htmx добавляет к кнопке функциональность (при помощи JavaScript), но эта функциональность дополняет HTML как язык гипермедиа. Htmx расширяет гипермедиа-систему веб-среды, а не заменяет эту систему совершенно иной архитектурой.
Хотя внешне две реализации очень похожи, кнопки на основе htmx и на основе JavaScript используют совершенно разные системные архитектуры и, как следствие, разные подходы к веб-разработке.
По мере того как мы будем разбирать построение приложений HDA, различия между двумя подходами будут становиться все более явными.
Гипермедиа часто, хотя и не всегда, отлично подходит для создания веб-приложения.
Возможно, вы строите сайт или приложение, которым просто не нужен высокий уровень интерактивности. Полезных веб-приложений такого рода очень много, и в этом нет ничего плохого! Таким приложениям, как Amazon, eBay, многим новостным сайтам, интернет-магазинам, форумам и т.д., просто не нужна избыточная интерактивность: они в основном состоят из текста и графики, а ведь это именно то, для чего создавался веб.
Возможно, бо́льшая часть ценности приложения создается на стороне сервера (координация пользователей, сложный анализ данных) с последующим представлением результатов пользователю. А может быть, приложение создает ценность, используя хорошо спроектированную базу данных с простыми операциями CRUD (Create-Read-Update-Delete, создать-прочесть-обновить-удалить). И здесь опять-таки нечего стыдиться!
Во всех этих случаях гипермедиа-решение может стать отличным вариантом: потребности таких приложений в интерактивности невелики, а большая часть их ценности сосредоточена на стороне сервера, а не на стороне клиента.
Во всех описанных случаях применимо то, что Рой Филдинг называл «крупномодульной гипермедийной передачей данных»: можно просто использовать якорные теги и теги форм с ответами, возвращающими целые документы HTML по запросам, и все будет работать нормально. Именно для этого создавался веб.
Применяя гипермедиа в таких приложениях, вы избавите себя от значительной сложности на стороне клиента, которая неизбежно сопровождает решения SPA: нет необходимости в маршрутизации на стороне клиента, управлении моделью на стороне клиента, ручном подключении логики JavaScript и т.д. Кнопка возврата «просто работает». Глубокие ссылки «просто работают». Вы сможете сосредоточить свои усилия на сервере, где создается реальная ценность приложения.
Кроме того, наложение htmx или другой гипермедиа-ориентированной библиотеки поверх такого решения позволит избавиться от многих проблем с удобством использования, присущих базовому HTML, и осуществлять более детализированную передачу данных гипермедиа. Все это открывает новые возможности для создания пользовательского интерфейса и взаимодействий, что значительно расширяет набор приложений, которые можно создавать на основе гипермедиа.
Впрочем, подробности позже.
Когда же гипермедиа не будет работать?
Пример, который сразу приходит на ум, — электронная онлайн-таблица. В электронной таблице обновление одной ячейки может привести ко множеству каскадных изменений во всей таблице. Что еще хуже, это может происходить при каждом нажатии клавиши.
В этом случае мы имеем чрезвычайно динамичный пользовательский интерфейс без четких ограничений по обновлениям, вызываемым конкретным изменением. Круговой обмен данных с сервером, характерный для гипермедиа, приведет к громадной потере производительности.
Эта ситуация не подходит для «крупномодульной гипермедийной передачи данных» в веб-среде. В таких приложениях, безусловно, стоит рассмотреть решение с нестандартным кодом JavaScript на стороне клиента.
Тем не менее даже в приложении электронной онлайн-таблицы, вероятно, найдутся области, в которых гипермедиа может принести пользу.
Скорее всего, в электронной таблице есть страница настроек. И возможно, к ней можно применить гипермедийный подход. Если эта страница представляет собой набор относительно простых форм, которые должны сохраняться на сервере, гипермедиа, очевидно, отлично подойдет для этой части приложения.
Кроме того, переход на гипермедиа позволит значительно упростить эту часть приложения. Возможно, удастся направить большую часть бюджета сложности приложения на нетривиальную рабочую логику электронной таблицы, сохраняя простые компоненты простыми.
Зачем применять сложный, мощный фреймворк JavaScript к чему-то столь же элементарному, как страница настроек?
Бюджет сложности
У любого программного проекта имеется (явно или неявно) бюджет сложности: объем сложности, с которым справляется команда разработки, ограничен, и каждая новая функциональность или выбор в процессе реализации хоть немного, но повышают общую сложность системы.
Главный минус сложности в том, что она стремится к экспоненциальному росту: сегодня вы держите всю систему у себя в голове и понимаете последствия конкретного изменения, а через неделю система выходит из-под контроля. Что еще хуже, усилия по контролю над сложностью (например, введение абстракций или инфраструктуры для управления сложностью) часто только повышают ее. Задача хорошего разработчика — удержать сложность под контролем.
Самый надежный способ ограничить сложность также и самый трудный: научиться говорить «нет». Отклонять запросы на добавление функциональности — настоящее искусство. Если вы научитесь делать это так, чтобы людям казалось, будто они сами сказали «нет», вы далеко пойдете.
Как ни печально, это получается не всегда: некоторая функциональность просто необходима. Тогда поставьте вопрос так: «Каково самое простое решение, которое будет работать?» Понимание возможностей гипермедиа-подхода дополнит ваш инструментарий «простейших решений» новыми средствами.
В веб-разработке гипермедиа часто считают устаревшей, изжившей себя технологией — возможно, полезной для статических сайтов, но определенно не подходящей для современных комплексных веб-приложений.
Серьезно? Мы заявляем, что на основе этой технологии можно строить современные веб-приложения?
Да, серьезно.
В отличие от расхожего мнения, гипермедиа — это инновационная и современная системная архитектура для построения приложений, в некоторых отношениях более современная, чем популярные решения SPA. В оставшейся части этой книги мы заново познакомим вас с основными практическими концепциями гипермедиа, а затем покажем, как пользоваться этой системной архитектурой для создания продуктов.
В следующих главах мы постараемся объяснить все преимущества и приемы, используемые в этом подходе. Надеемся, вы станете таким же поклонником гипермедиа, как и мы.
Самый известный пример грязного HTML — каша из <div>.
Когда разработчикам приходится пользоваться обобщенными элементами <div> и <span> вместо более содержательных тегов, это либо приводит к снижению качества их веб-сайтов, либо они делают лишнюю работу, а скорее всего, и то и другое.
Например, вместо добавления кнопки в виде специализированного элемента <button> к элементу <div> может быть присоединен прослушиватель события click.
<div class="bg-accent padding-4 rounded-2" onclick="doStuff()">Сделать
что-нибудь</div>
У такой кнопки два основных недостатка.
• Она не может получить фокус — к ней нельзя перейти клавишей Tab.
• Вспомогательные инструменты разработки не смогут определить, что это кнопка.
Да, проблемы можно решить добавлением атрибутов role="button" и tabindex="0":
<div class="bg-accent padding-4 rounded-2"
role="button"
tabindex="0"
onclick="doStuff()">Сделать что-нибудь</div>
Это простые решения, но их приходится помнить. Из исходного кода HTML не очевидно, что это кнопка. Поэтому будет сложнее прочитать код и заметить отсутствие этих атрибутов. Исходный код страниц с кашей из <div> труднее редактировать и отлаживать.
Чтобы избежать создания каши из <div>, мы рекомендуем изучить спецификацию доступных тегов HTML и относиться к каждому тегу как к еще одному инструменту из доступного набора. Вы даже можете узнать что-то новое для себя! (Хотя если учесть, что на сегодняшний день в спецификации определено 113 элементов, это скорее мастерская, а не ящик с инструментами.)
Конечно, не для каждого UI-паттерна найдется специальный элемент HTML. Часто приходится объединять элементы и дополнять их атрибутами. Но прежде чем делать это, перетряхните свой инструментарий HTML. Просто невероятно, сколько полезного в нем можно найти.
2 https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
3 https://htmx.org/
Система гипермедиа состоит из нескольких компонентов, в числе которых:
• среда гипермедиа, например HTML;
• сетевой протокол, например HTTP;
• сервер, предоставляющий API гипермедиа, посылающий гипермедиа в ответ на сетевые запросы;
• клиент, корректно интерпретирующий эти ответы.
В этой главе мы рассмотрим эти компоненты и их реализацию в контексте веб-среды.
После обзора основных компонентов веб-среды как системы гипермедиа мы перейдем к рассмотрению некоторых идей, лежащих в основе этой системы, — в том виде, в каком они были разработаны Роем Филдингом в его диссертации «Architectural Styles and the Design of Network-based Software Architectures». Вы узнаете, откуда взялись термины REST (REpresentational State Transfer), RESTful и HATEOAS (Hypermedia As The Engine Of Application State). Мы проанализируем эти термины в контексте веб-среды.
Все это поможет вам глубже понять теоретическую основу Всемирной паутины как системы гипермедиа, предпочтительную схему взаимодействия ее компонентов и то, почему гипермедиа-управляемые приложения являются RESTful-приложениями, а JSON API — нет (невзирая на то, как сейчас в отрасли принято использовать термин REST).
Фундаментальной технологией системы гипермедиа является среда гипермедиа, которая позволяет клиенту и серверу динамически и нелинейно взаимодействовать друг с другом. Напомним, что гипермедиа делает таковым именно присутствие элементовуправлениягипермедиа, то есть элементов, позволяющих пользователям выбирать нелинейные действия в гипермедиа-среде. Возможности взаимодействия пользователя с информационной средой не ограничиваются простым чтением от начала к концу.
Мы уже упоминали о двух основных гипермедийных элементах управления HTML — якорях и формах, позволяющих представлять ссылки и операции пользователю непосредственно через браузер.
В случае HTML эти ссылки и формы обычно задают цель своих операций в форме унифицированных указателей ресурсов, или URL (Uniform Resource Locators):
Унифицированный указатель ресурсов — текстовая строка, ссылающаяся, или указывающая, на сетевой каталог, из которого может быть загружен ресурс, а также механизм загрузки этого ресурса.
URL представляет собой строку, состоящую из нескольких подкомпонентов.
Листинг 7. Компоненты URL
[схема]://[информация_пользователя]@[хост]:[порт][путь]?[запрос]#[фрагмент]
Многие из этих подкомпонентов необязательны и часто опускаются.
Типичный URL может выглядеть примерно так:
Листинг 8. Простой URL
https://hypermedia.systems/book/contents/
Этот конкретный URL состоит из следующих компонентов:
• Протокол или схема (в данном случае https);
• домен (в данном случае hypermedia.systems);
• путь (в данном случае /book/contents).
Этот URL однозначно идентифицирует ресурс, доступный в интернете, запросы HTTP к которому могут отправляться клиентом гипермедиа, поддерживающим HTTPS, например веб-браузером. Если этот URL представлен как ссылка гипермедийного элемента управления внутри документа HTML, это указывает на то, что на другом конце сети находится сервер гипермедиа, который также поддерживает HTTPS и может ответить на запрос представлением указанного ресурса (или перенаправить в другое место и т.д.).
Учтите, что URL часто не записываются в HTML полностью. Очень часто встречаются якорные теги, которые могут выглядеть примерно так:
Листинг 9. Простая ссылка
<a href="/book/contents/">Содержание</a>
Здесь используется относительная гипермедийная ссылка, которая, какпредполагается, содержит протокол, хост и порт «текущего документа», то есть протокол и сервер, использованные для загрузки текущей страницы HTML. Таким образом, если эта ссылка будет найдена в документе HTML, загруженном по адресу https://hypermedia.systems/, то предполагаемый URL для этого якорного тега будет иметь вид https://hypermedia.systems/book/contents/.
Приведенный выше элемент гипермедиа (ссылка) сообщает браузеру: «Когда пользователь щелкает на этом тексте, отправить запрос к https://hypermedia.systems/book/contents/ с помощью протокола HTTP».
HTTP — протокол, используемый для передачи HTML (гипермедиа) между браузерами (клиентами гипермедиа) и серверами (серверами гипермедиа); как следствие, он также является ключевой сетевой технологией, связывающей воедино распределенные гипермедиа-системы веб-среды.
HTTP версии 1.1 — относительно простой сетевой протокол, поэтому посмотрим, как будет выглядеть запрос GET, инициированный якорным тегом. Этот запрос будет отправляться серверу, найденному по адресу hypermedia.systems, на порт 80 по умолчанию:
GET /book/contents/ HTTP/1.1
Accept: text/html,*/*
Host: hypermedia.systems
Первая строка сообщает, что это запрос HTTP GET, и указывает путь к запрашиваемому ресурсу. Строка завершается версией HTTP для запроса.
Далее следует серия заголовков запроса HTTP: отдельные строки с парами «имя/значение», разделенными двоеточием. Заголовки запроса предоставляют метаданные, которые могут использоваться сервером для определения того, какой ответ возвращать на запрос клиента. В данном случае при помощи заголовка Accept браузер указывает предпочтительный формат ответа — HTML, но также сообщает, что примет любой ответ сервера.
Затем идет заголовок Host, который сообщает, какому серверу был отправлен запрос. Эта информация может быть полезной, если на одном хосте размещаются несколько доменов.
Ответ HTTP от сервера на запрос может выглядеть примерно так:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 870
Server: Werkzeug/2.0.2 Python/3.8.10
Date: Sat, 23 Apr 2022 18:27:55 GMT
<html lang="en">
<body>
<header>
<h1>СИСТЕМЫ ГИПЕРМЕДИА</h1>
</header>
...
</body>
</html>
В первой строке ответа HTTP указывается используемая версия HTTP, за которой следует код ответа 200; он означает, что указанный ресурс был найден, а запрос обработан успешно. Далее следует строка OK, которая соответствует коду ответа. (Фактическая строка роли не играет, результат запроса сообщается клиенту в виде кода ответа — более подробно мы разберем это ниже.)
После первой строки ответа, как и в запросе HTTP, следует серия заголовков ответа, которые предоставляют клиенту метаданные, помогающие обеспечить корректное представление ресурса.
В конце мы видим новый контент HTML. Контент содержит представление запрашиваемого ресурса в формате HTML, в данном случае оглавление книги. Браузер использует эту разметку HTML для замены всего содержимого отображаемого окна, показывает пользователю новую страницу и обновляет адресную строку новым URL.
Приведенный выше якорный тег выдает запрос HTTP GET, где GET — метод запроса. Метод, указанный в запросе HTTP, по сути, содержит самую важную информацию о запросе (после собственно ресурса, к которому обращен запрос).
В HTTP доступно множество методов; чаще всего разработчикам могут пригодиться следующие из них:
• Запрос GET получает представление конкретного ресурса. Запросы GET не должны изменять данные.
• Запрос POST отправляет данные указанному ресурсу. Часто это приводит к изменению состояния на сервере.
• Запрос PUT заменяет данные указанного ресурса. Это приводит к изменению состояния на сервере.
• Запрос PATCH заменяет данные указанного ресурса. Это приводит к изменению состояния на сервере.
• Запрос DELETE