Что такое гипермедиа примеры

Гипермедиа

Всемирная Паутина — классический пример гипермедиа, где интерактивные единицы соседствуют с мультимедийными.

Программы для создания гипермедиа

Оглавление вставляется в каждый текстовый файл, указанный в диаграмме. Медиа файлы указываются в оглавлении, но правка в них не вносится. Таким образом, текстовые и медиафайлы автоматически связываются гиперссылками. Подробнее см.: http://d2h.sf.net.

Литература

Что такое гипермедиа примеры. Смотреть фото Что такое гипермедиа примеры. Смотреть картинку Что такое гипермедиа примеры. Картинка про Что такое гипермедиа примеры. Фото Что такое гипермедиа примеры

Полезное

Смотреть что такое «Гипермедиа» в других словарях:

гипермедиа — Представление данных в виде информационных блоков, соединенных гиперсвязями. Примечание Гиперсвязь представляет собой однонаправленное логическое соединение между двумя различными блоками данных в информационно телекоммуникационной сети. [ГОСТ Р… … Справочник технического переводчика

гипермедиа — сущ., кол во синонимов: 1 • гиперсреда (1) Словарь синонимов ASIS. В.Н. Тришин. 2013 … Словарь синонимов

ГИПЕРМЕДИА — (от греч. hyper – над, сверх + англ. media – средства). Система организации информации, содержащая текст, аудио и видеофрагменты, соединенные гиперссылками. См. гипертекст … Новый словарь методических терминов и понятий (теория и практика обучения языкам)

HyperCard — Тип Гипермедиа Разработчик Apple Inc. (раньше App … Википедия

гиперсреда — гипермедиа Метод организации информации, поддерживающий множественные взаимосвязанные пути доступа к элементам информационного массива и позволяющий легко осуществить переходы от одного информационного раздела к другому, которые могут быть… … Справочник технического переводчика

Гиляревский, Руджеро Сергеевич — (р. 31.08.1929) филолог, спец. в обл. информатики, научных и массовых коммуникаций; д р филол. наук, проф. Род. в Москве. Окончил исп. отделение филол. ф та МГУ (1953), асп. библиотечного ф та Моск. гос. ин та культуры (1958). С 1964 доц.… … Большая биографическая энциклопедия

ИНТЕРНЕТ — (InterNet) (англ. взаимо сеть или сеть сетей) феномен культуры, конституировавшийся в последней трети 20 в. на технологической основе общемировой системы компьютерных сетей и в определенном смысле представляющий собой модельную объективацию… … История Философии: Энциклопедия

ИНТЕРНЕТ И ДРУГИЕ КОМПЬЮТЕРНЫЕ СЕТИ — Компьютерная сеть это группа компьютеров, которые соединены между собой таким образом, чтобы был возможен обмен данными между ними. Работу компьютерных сетей обеспечивают компоненты трех основных типов: 1) компьютеры; 2) средства передачи, такие … Энциклопедия Кольера

Источник

Hypermedia — то без чего ваше API не совсем REST

Всем привет! Меня зовут Дмитрий Павлов, в компании Align Technology мы с коллегами занимаемся разработкой Web API для взаимодействия внутренних систем и интеграции нашей компании со сторонними вендорами. Об идеях создания API для веба, а точнее RESTful API я хотел бы рассказать в этой статье.

В последние годы тема Web API стала очень популярна, многие компании занимаются созданием подобных интерфейсов, как открытых, так и для внутреннего пользования. В описании Web API практически всегда можно встретить акроним REST, но что же это обозначает этот термин и правильно ли его используют?

REST или не REST?

Большинство разработчиков, особенно в России, понимает под REST программный интерфейс, работающий с использованием протокола HTTP[S] при условии соблюдения следующих свойств:

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

Более широкое использование HTTP методов: не ограничиваемся GET и POST, добавляем PUT и DELETE. В некоторых API можно встретить еще и PATCH.

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

и изучив её выполнять запросы к ресурсам (что обычно выражается в написании клиента, который по заданным форматам URL’ов подставляет параметры и обрабатывает ответы).

Примеров таких API на просторах сети предостаточно, до недавнего времени у Яндекса многие API (раз, два) заявленные как REST работали по этой схеме.

Hypermedia в сообщениях

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

Применение такого подхода обычно означает, что клиент знает некоторый конечный набор «точек входа» (можете считать их аналогами стартовых страниц на сайтах), с которых он начинает свое взаимодействие с API, используя предоставленную в представлении ресурса информацию для навигации к другим ресурсам и совершения действий.

Для достижения этой задачи как раз и используются гиперссылки (hypermedia):

Отсутствие ссылки как на связанные ресурсы, так и на доступные действия означает, что данная операция недоступна в текущем состоянии ресурса.

Пример переработки API «Рецепты печенек» в Hypermedia представление

Возвращаясь к примеру с нашим API о каталоге рецептов печенек, преобразуем его в Hypermedia-вид.

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

Значительное отличие от оригинальной версии заключается в появлении объекта links внутри каждого ресурса. Ключи этого объекта представляют собой relation’ы (те самые идентификаторы), а значения — ссылки. В результате наши ресурсы не требуют дополнительной информации (вне самого ресурса) о том как же перейти из каталога рецептов к детальному описанию, ссылка встроена в представление ресурса.

Данные подход позволяет легко расширять функциональность нашего API. Предположим, что мы для каждого рецепта хотим предоставить клиенту набор рекомендаций, представимый в виде списка рецептов. Сделать это очень легко, достаточно добавить в наш объект links новый ключ:

Аналогично, совершенно не составит труда добавить идентификацию ингредиентов как отдельных ресурсов, если в этом возникнет необходимость.

Содержание URI не играет никакой роли, ведь теперь элементом API является relation, и мы без каких либо изменений на клиенте можем поменять ссылку на /recipes/related-to/Овсяное печенье с шоколадом или на /recipes/234892skfj45sdlkfjdsa12

Hypermedia на службе перемен

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

Для наглядности рассмотрим пример с нашим API, добавив hypermedia-контрол для создания нового рецепта.

Данный подход позволяет нам не описывать статический набор операций и условия их выполнения в документации, а непосредственно серверу контролировать какие операции клиент может совершать над ресурсом в данный момент времени, а какие — нет. Добавление новых действий тоже не представляет сложности: мы просто объявляем новый relation, и начинаем включать его в представление ресурса, которое формирует сервер.

Разумеется, предоставление ссылок не снимает с сервера ответсвенности за корректное оперирование HTTP методами и соблюдения их семантики :).

А как же relation?

У вас к данному моменту наверняка возник вопрос: какой смысл затевать все это, если для эффективной работы клиент все равно должен понимать смысл relation’ов? По ним-то документация должна иметься.

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

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

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

Hypermedia types или почему application/json нам не подходит

Ресурсы глазами машины

Глядя на получившиеся у нас ресурсы, человек сразу выделяют ссылки, что создает впечатление о корректном формате нашего сообщения. Мы делаем вывод об этом, анализируя содержимое сообщения, тогда так стандарт предписывает смотреть на Content-Type заголовок ответа.

Рассмотрим следующий ответ сервера:

Нам очевидно, что в ответе содержится xml-документ, но Content-Type предписывает воспринимать содержимое как простой текст, поэтому то, что он похож на xml-документ может быть просто совпадением или частным случаем. Именно поэтому верный Content-Type так важен.

Vendor specific типы

Одним из способов решить проблему корректности Content-Type’а — использовать свой собственный. В документации мы явно укажем, где у нас в сообщении расположены ссылки. Если клиент получил от сервера ответ с нашем личным Content-Type’ом, ему не нужно будет динамически угадывать, что ссылка а что нет, если конечно он понимает наш Content-Type. Стоит отметить, что зачастую документация с описанием типа содержит не только подробности самого формата (т.е. где расположены ссылки, а где свойства), но и другую информацию:

Hypermedia типы общего назначения

На первый взгляд, vendor specific типы решают возникшую проблему со ссылками, но у них есть и свои проблемы:

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

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

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

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

В описании всех таких форматов вы найдете, как и куда помещать свойства ресурса, в каком виде оформлять ссылки на другие ресурсы.

Различаются они форматом и возможностями, которые содержатся в самом типе.

Разница в форматах или принципиальность создателей

Большинство типов общего назначения отличается незначительными деталями, например, как форматировать ссылки. Так, в HAL ссылки выглядят следующим образом:

Тогда как Siren представляет их так:

Основное отличие здесь в представлении relation значений. Создатель HAL стремился сделать формат более лаконичным, в то время как создатель Siren — более полным: relation у ссылки действительно может быть сложным (поэтому в Siren это массив значений), но это не всегда используется (поэтому в HAL это скаляр, да еще и ключ в объекте).

Такие вот разные взгляды и привели к созданию разных форматов, об одном формате договориться не смогли.

Различие в возможностях

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

Generic vs vendor specific

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

Одно из главных преимуществ hypermedia-типа общего назначения — экономия времени вам и клиентам вашего API. Вот за счет чего она достигается:

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

В итоге для большинства задач можно рекомендовать использовать один из имеющихся Hypermedia-форматов общего назначения по умолчанию и делать выбор в пользу vendor-форматов в сложных или специфических случаях (если вы, конечно, не ставите целью vendor lock-in).

Насколько мне нужно все это?

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

Можно отметить, что концепция точек входа способна привести к росту числа запросов, чтобы «добраться» до нужного ресурса и что включая ссылки мы делаем сообщение более объемным по сравнению с голыми данными.

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

Основной плюс REST-подхода (здесь я имею ввиду полноценный REST) в гибкости и расширяемости, который он предоставляет, позволяя нам добавлять новые возможности или просто менять организацию ресурсов у себя на сервере без нарушения работы существующих клиентов.

Даже если вы решите не использовать hypermedia в вашем API, теперь вы знаете, что без нее REST — это не REST, а просто Web API. Это не делает API плохим или хорошим, я просто констатирую факт. Главное не забывать, что API мы делаем не ради самого API, а для решения задач, стоящих перед нами :).

Источник

Гипермедиа

Оглавление

задний план

Многие авторы используют термины гипертекст и гипермедиа как синонимы ( Jakob Nielsen 1995 и Rainer Kuhlen 1997). Расширенное понимание « текста » из семиотики также указывает на правомерность этого уравнения. Однако, т.е. игнорировали разные временные характеристики различных форм СМИ. Более того, эта точка зрения противоположна столь же обсуждаемому мультимедийному аспекту.

Интерфейс приложения

Проблемы с мультимедийным гипертекстом

Центральная проблема мультимедийного гипертекста получается путем интеграции во временном измерении (то есть во время создания гипертекста точно не известно) асинхронных (фильм / анимация / видео и звук / речь / музыка) и динамических элементов.

Обычный текст может, например, использоваться как названная отправная точка для запуска показа видеофильма; однако это решение часто рассматривается как не очень гипермедийное и недостаточное. Альтернативный подход был разработан в MIT Media Lab для проекта Elastic Charles ; маленькое движущееся изображение ( micon [ движущийся значок ], по-английски «движущаяся иконограмма») служит отправной точкой для гиперссылки.

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

Области применения гипермедийных систем

Концепции гипермедиа позволяют использовать множество возможных приложений:

Источник

REST в реальном мире и практика гипермедиа

Как правильно построить архитектуру приложения, с учетом специфики REST? Было ли с вами такое, что словом «REST» называют любое HTTP API без разбору — и как донести истинное значение этого термина? Как показать, что преимущества REST проявляются в больших долгосрочных проектах, но для небольшой утилиты лучше взять что-то попроще? Эти и другие животрепещущие вопросы освещает Дилан Битти (Dylan Beattie) в докладе «Real world REST and Hands-On Hypermedia».

Дилан — системный архитектор и разрабточик, за жизнь успевший поучаствовать во множестве проектов, от небольших вебсайтов до огромных распределенных систем; от легаси с двадцатилетней историей до самых новейших разработок. Сейчас он работает архитектором в Spotlight и занимается решением сложных задач в современных распределенных системах. Создание правильных, красивых и эффективных HTTP API является частью его работы, и он действительно знает в них толк.

Вы сможете встретиться с Диланом вживую на конференции DotNext Moscow 2017, куда он приедет с новым докладом «Life, liberty and the pursuit of APIness: the secret to happy code». Напоминаем, что вы можете купить билеты по вкусной цене вплоть до 31 октября включительно.

Эту статью можно либо прочитать в текстовой расшифровке (жмите кнопку «читать дальше» ⇩), либо посмотреть полную видеозапись доклада. Все необходимые для понимания изображения, слайды и диаграммы присутствуют как на видео, так и в текстовой расшифровке, так что вы ничего не потеряете.

Комментарии к статье приветствуются и действительно важны — мы постараемся задать ваши лучшие вопросы напрямую Дилану на DotNext Moscow 2017.

Сегодня мы поговорим об идеологии REST в реальном мире и практическом воплощении гипермедиа.

Но сначала немного обо мне.

Меня зовут Дилан Битти (Dylan Beattie). Лучший способ задать любые вопросы по докладу — найти меня в twitter (@dylanbeattie). У меня есть страница ВКонтакте, но я не говорю по-русски, поэтому в этой социальной сети у меня нет друзей.

На протяжении долгого времени я занимаюсь созданием веб-сайтов. Свою первую веб-страницу я создал еще в 1992 году, когда World Wide Web исполнился один год. Кроме того, я разрабатываю веб-приложения.

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

Мой сайт: dylanbeattie.net. Там я публикую свои заметки об архитектуре программного обеспечения, REST и других подобных вещах. Также хочу упомянуть, что код со всех слайдов есть на GitHub: github.com/dylanbeattie/dotnext/. Вы можете загрузить его оттуда и протестировать самостоятельно.

Но давайте поговорим про REST.

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

Это Рой Филдинг. Рой изобрел REST и определил, что это такое. Существует много материалов, посвященных ПО и вычислительной технике, где объясняется, как все работает. Используемые слова имеют различный смысл для разных людей. Но REST имеет очень четкое определение, которое мы и обсудим вначале.

Сейчас Рой старший научный сотрудник Adobe. А ранее он работал над Apache. Фактически он является одним из основателей проекта веб-сервера Apache и он же был одним из авторов HTTP — базового протокола, который связывает World Wide Web воедино. В 2000 году Рой опубликовал диссертацию «Архитектурные стили и дизайн сетевых программных архитектур». В этой работе он описывает стили архитектуры масштабируемого программного обеспечения в Сети.

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

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

Первая — связанный набор архитектурных ограничений, получив имя, становится архитектурным стилем. На его взгляд, на этот вопрос повлияла архитектура (в контексте строительства), он много думал, в том числе, и об архитектурных стилях. Здания друг от друга отличает не проект, не дизайн — а стиль: набор индивидуальных особенностей и ограничений. И REST подобен ему. Это набор шаблонов, которые вы можете применить к своим системам.

Еще я считаю очень важным, что «REST в разработке программного обеспечения существует в масштабе десятилетий. Каждая деталь обеспечивает долговечность и независимую эволюцию программного обеспечения». REST предназначен для создания систем, которые будут работать годами, а может быть, десятилетиями. Если в следующем месяце у вас ожидается окончание финансирования, вероятно, вы не должны создавать систему, соответствующую постулатам REST, потому что многие из представленных в рамках этой концепции ограничений прямо противоположны краткосрочной эффективности.

Часто бывает так, что в проекте, над которым вы работаете, есть два или больше способов решения проблемы. И путь, который ведет к REST, зачастую занимает больше времени. На этом пути вы должны думать о множестве вещей, которые могут не являться проблемой для вас и вашей компании. Так что будьте очень внимательны. Подумайте о том, чего именно вы пытаетесь достичь. Если вам повезло работать над системой, которой предстоит функционировать много лет, в рамках этой статьи вы найдете много идей, которые, надеюсь, будут вам полезны.

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

Определение REST

Рой Филдинг предложил определение REST — это скоординированный набор архитектурных ограничений.

Клиент-сервер

В первую очередь, по его словам, программная система должна быть построена для работы на клиенте и на сервере. Я надеюсь, что это никого не удивляет. Большинство из нас, думаю, уже создавали клиент-серверные приложения — веб-сайты, системы электронной почты, FTP. Сейчас это очень распространено.

Я не буду описывать детали. Ваш сервер как-то делится между клиентами, обеспечивая хранилище данных, основные функции и безопасность, — те вещи, которыми вы хотите управлять централизованно.

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

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

Не храним состояние

Второе ограничение связано с отказом от хранения состояния. В ASP.NET, PHP, ColdFusion или классическом ASP вы сталкиваетесь с идеей сеанса. Таким образом, у вас есть cookie сеанса. Но эта идея больше не работает. Когда у вас было что-то вроде ASP.NET и вы запускали один веб-сервер, он начинал понемногу замедляться. Потом вы устанавливали другой веб-сервер, и в конце концов все переставало работать из-за того, что каждый раз при отправке запроса на сервер выделялось некоторое пространство в хранилище только под этого клиента. Примерно так:

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

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

Поэтому, избегая хранения состояния, вы получаете большую гибкость в отношении того, сколько клиентов вы можете обслуживать и как вы можете масштабировать систему.

Кеширование

Третье ограничение, которое определяет Рой, — это кеширование.

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

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

Многоуровневая система

Следующее ограничение напрямую связано с идеей кэширования. Это идея многоуровневых систем. Мой любимый пример данной идеи — кеширующий прокси-сервер между клиентами и сервером.

Клиенты на этой схеме слева. Предположим, это различные варианты смартфонов — iPhone, Samsung, Android — все, что угодно. Прокси-сервер — в середине цепочки. Допустим, им управляет некая большая телекоммуникационная компания. Как владелец сервера, вы платите за работу того, что справа от прокси. Ведь когда приходит запрос от клиент, сервер выполняет некоторые расчеты. А это стоит денег — электричества, амортизации оборудования и т.п.

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

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

Что такое гипермедиа примеры. Смотреть фото Что такое гипермедиа примеры. Смотреть картинку Что такое гипермедиа примеры. Картинка про Что такое гипермедиа примеры. Фото Что такое гипермедиа примеры

В этом примере клиенты взаимодействуют с прокси-сервером. Прокси считает, что он взаимодействует с сервером, но на самом деле он отправляет запросы на уровень безопасности (например, брандмауэр). Тот, в свою очередь, считает, что общается с сервером, он фактически отправляет запросы на балансировщик нагрузки.

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

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

Единый интерфейс

До появления HTTP и REST, если вы хотели получить некоторую информацию с сервера, вам предстояло выбрать один из нескольких десятков протоколов — Gopher, FTP, Telnet и т.п. Все это были разные системы, и каждая подразумевала свой способ взаимодействия с удаленной информацией и удаленными службами.

HTTP и REST стандартизировали это. Прежде всего, была стандартизирована идентификация ресурсов — появился URL-адрес (забавно думать, что кто-то придумал URL). Одна часть адреса определяет протокол (HTTP), другая — путь к ресурсу, а третья — порт. Все в интернете, доступное для сетевых запросов, может быть идентифицировано с использованием одного из этих URL-адресов.

Манипуляции с представлениями

Под манипуляциями с представлениями подразумевается то, что вы можете запросить данные в разных форматах. Если вам нужен фрагмент данных, вы можете получить его как таблицу CSV, файл Excel, текстовый документ, jpeg. Это все реальные представления некоторых базовых результатов.

Вы должны смочь понять, что происходит в сети. В HTTP есть запросы GET, PUT, POST, DELETE. Они описательны: GET — это английское слово, которое означает, что вы хотите получите что-то. PUT означает положить нечто, DELETE — удалить. Вы можете посмотреть сетевой трафик в некотором инструменте для интеллектуальной отладки и понять, какие запросы отправлялись на самом деле.

Гипермедиа в качестве механизма управления состоянием приложения

Об этомы мы поговорим подробнее.

Кодировка по запросу

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

Я никогда не видел API, который это делает. Я видел множество веб-приложений: Google Docs Offline, Gmail и множество других одностраничных приложений. Я не поддерживаю идею получения запускаемого кода из чужого API для последующего запуска в моей системе. Но приятно знать, что существует возможность такого запуска операций на клиентах.

Я пришел в отрасль, когда создавались первые веб-браузеры, которые не являлись почтовыми клиентами. Затем кто-то решил, что можно запускать JavaScript, и теперь мы можем создать почтовый клиент в JavaScript и отправить его клиенту так, чтобы он смог запустить его в браузере.

Обязательность ограничений

Важная вещь заключается в том, что Рой Филдинг прямо говорит: существует 6 ограничений, и только одно из них опционально.

Если вы строите систему и решаете возникающие проблемы описанным образом, то система будет RESTful. Если же вы решаете их по-другому — система будет не RESTful. Это не значит, что она хорошая или плохая. Определение выше ничего не говорит о качестве системы. Однако очень важно, чтобы мы договорились о том, что представляет собой RESTful API по определению (в соответствии с первоисточником).

Посмотрим, как указанные ограничения будут выглядеть в реальной жизни, а точнее, в жизни героев из комиксов. Попробуем написать код социальной сети для супергероев в соответствии с REST. Это будет весело.

REST на практике

Здесь изображены действительно интересные персонажи из комиксов (и фильмов по комиксам). Попробуем создать для них социальную сеть. Но мы не хотим увязнуть в разработке пользовательского интерфейса, так же как не хотим тестировать JavaScript. Поэтому давайте просто создадим API.

Вот наша точка входа:

в ответ мы получаем:

Давайте создадим конечную точку, называемую здесь «/ profiles», которая будет иметь два метода:

Метод возвращает массив JavaScript — JSON из профайлов всех супергероев, которые присоединились к социальной сети:

В данный момент мы не беспокоимся о безопасности, этот вопрос за рамками нашей беседы.

Второй метод — POST. Отправляя POST в /profiles, вы даете полезную нагрузку в виде JSON.

Ответ — сообщение об успешном создании профиля и его адрес:

Разместим описание сервиса и его API где-либо в интернете, чтобы каждый знал, как пользоваться нашей системой:

… и отправляемся на выходные.

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

И вдруг звонит телефон. Мы берем трубку, а на другом конце провода кто-то говорит: «Ваш API забил весь наш канал!». А затем еще звонок: «Ваш идиотский API перегружает нашу базу данных».

В чем здесь проблема? Что произошло? Почему все нами недовольны? Потому что в ответе на запрос мы шлем два миллиона записей. У нас есть только одна конечная точка — /profiles. Единственное, что вы можете сделать с API, — это получить или опубликовать данные. И если вы попробуете это сделать, каждый раз будете получать 2 миллиона записей. Таким образом, каждый раз, когда кто-то пытается использовать наш API, он получает мегабайты данных. Сеть падает, база данных — тоже. Вся система не масштабируется.

Что мы можем с этим сделать? Давайте возьмем конечную точку и разобьем ее:

Далее мы можем запросить страницу 2:

Это очень просто, и это работает. Я уверен, что большинство из нас может создать систему, которая делает это. А когда мы получаем «No Content», это значит, что у вас есть все профили системы.

Однако это не REST. И причина в том, что API не использует гипермедиа в качестве двигателя состояния приложения. Когда мы получаем первую страницу, теоретически мы можем перейти оттуда на страницы 2, 3. Но в ответе сервера нет ничего, что говорит нам о такой возможности.

Что мы будем с этим делать?

Прежде чем дать ответ, напомню вам об одной серии книг из детства.

Это книги серии «Выберите свое приключение». Они существовали раньше, чем мы узнали, что такое даже 8-битный компьютер. На первой странице представлена часть истории, а в конце — выбор того, что вы хотите сделать дальше.

В качестве примера я создал специальный текст для нашей ситуации:

Это «Выбери себе приключение» специально для DOTNEXT в Санкт-Петербурге.

«У вас был УДИВИТЕЛЬНЫЙ первый день на DotNext в Санкт-Петербурге. Теперь вы на конференции после вечеринки. Это был напряженный день; может, вам стоит пойти в свою комнату и поспать? Но некоторые люди собираются заказать суши. Или вы можете остаться на вечеринке и посмотреть, как Евгений поет караоке?»

Этот контент — начало истории. А затем у нас есть операции гипермедиа, встроенные в представление результатов:

«Чтобы пойти в свою комнату и поспать, перейдите на стр. 23,
Чтобы съесть суши, перейдите на страницу 41,
Чтобы остаться на вечеринке и посмотреть караоке, перейдите на страницу 52.»

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

Давайте посмотрим, как это на самом деле выглядит в коде. Мы будем использовать для этого формат hal+json. Это json с дополнительными битами для языка репликации гипермедиа. Причина, по которой я его использую, заключается в том, что этот формат довольно короткий, поэтому его легко разместить на слайдах PowerPoint.

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

Введем переменную index — это страница, на которой вы находитесь. Total — общее количество записей в коллекции.

Давайте посмотрим на код.

Но прежде всего хочу предупредить: вы можете заметить здесь некоторые странные символы. Это C#. Я использую FiraCode, который обозначает следующее:

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

Для демонстрации я буду использовать инструмент, который создал для работы с такими вещами. Его можно найти в моем репозитории GitHub (ссылка в начале статьи).

Это просто инструмент API Explorer, запущенный внутри браузера. С одной стороны, у вас есть веб-браузеры, которые отлично справляются с просмотром страниц, покупкой вещей на Amazon и Ebay. Все они очень хорошо работают с API. С другой стороны, у нас есть инструменты, такие как Callcommandline, или специальные, вроде Postman. Они хорошо подходят для выполнения одного запроса. Но когда вы хотите перемещаться по системе гипермедиа, их использовать не стоит. Мой инструмент находится где-то между этими двумя крайностями: работает в браузере (все это работает на JavaScript) и понимает гипермедиа.

Мы собираемся использовать наш API. Вводим /profiles и нажимаем go.

В ответ получаем сообщение об успешном выполнении — 200 OK — и два миллиона записей (большое спасибо тому в интернете, кто взял каждого супергероя комиксов и поместил в большую электронную таблицу; мне было достаточно только скопировать и выложить все это для демонстрации).

Давайте посмотрим код, который обеспечил такой ответ.

Web API

Что такое гипермедиа примеры. Смотреть фото Что такое гипермедиа примеры. Смотреть картинку Что такое гипермедиа примеры. Картинка про Что такое гипермедиа примеры. Фото Что такое гипермедиа примеры

У нас есть ProfilesController (который наследует ApiController). Есть база данных DemoDatabase(), а также публичный объект Get(), который возвращает db.ListProfiles().

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

Вот что у нас получается:

У нас все еще выводятся два миллиона записей, но теперь массив находится внутри JSON-объектов JavaScript. Это означает, что у нас есть место, куда мы можем интегрировать больше функций.

Первое, что мы хотим сделать, — сократить вывод. Просто введем константу, обозначающую количество результатов на странице. Это будет 10. А затем мы переходим к базе данных и говорим:

Теперь когда мы обратимся к базе данных, она выдаст нам только 10 профайлов. Вот полный код Get():

Возвращаемся в наш инструмент и обновляем страницу. Вместо 2 миллионов получаем 10 записей (это видно по полосе прокрутки).

Мы решили проблему. Теперь запрос /profiles больше не приведет к сбою интернет-соединения.

Следующая вещь, которую мы хотим сделать, — ссылки для запроса страницы. Наш API достаточно умен, чтобы выдавать нужную страницу.

Однако пользователь не знает о такой возможности, поэтому пока эта система не соответствует REST.

Нам необходимо вернуться в код и кое-что поправить.

У нас есть результат, который является анонимным типом. Поэтому мы можем добавить в него все, что нам нравится. В частности, ссылки. Здесь мы будем использовать интерполяцию строк C#:

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

Вернемся к нашему API Explorer. Посмотрим, что произойдет:

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

У нас есть страница 0, и вы можете перемещаться по страницам.

Но с API все еще остались некоторые проблемы. Нам нужна навигация: мы должны иметь возможность двигаться вперед и назад по страницам, а также перемещаться к началу или к концу списка. Пока API этого не поддерживает. Кроме того, когда мы дойдем до конца коллекции, система начнет возвращать нам пустые массивы.

Чтобы API полностью соответствовал концепции REST, нам нужно добавить немного логики для расчета, куда мы можем отправиться с текущей страницы.

Для этого я использую маленький вспомогательный класс.

Здесь статический метод возвращает динамический объект. Что он делает? Мы даем ему индекс текущей страницы, количество элементов на каждой странице, а также общее количество элементов, и выполняем некоторые вычисления — получаем номера первой и последней страницы. Первый всегда будет равен нулю, последний — всегда будет содержать профайл с максимальным индексом в коллекции. Далее для индекса больше нуля мы можем вернуться назад. Однако мы не можем вернуться назад, и если index — count меньше минимального индекса; также мы можем идти вперед, но не сможем пройти мимо конца.

Метод возвращает ссылки. Теперь вернемся в наш код, переписав его следующим образом:

Теперь у нас есть ссылки на первую, последнюю, следующую и предыдущую страницы. Мы можем пойти вперед или назад; доступные для перехода ссылки учитывают, дошли ли вы до первой или последней страницы (с первой страницы нельзя пойти назад, с последней — вперед).

Таким образом, у нас было 2 миллиона записей в социальной сети. Мы разбили данные на отдельные страницы и затем использовали гипермедиа, чтобы любой, кто получает доступ к ресурсу, знал, как он может перемещаться по коллекции.

Развертывание ресурсов

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

Предположим, у нас в сети есть Железный Человек — Тони Старк. И у него в друзьях Hulk, Spider-Man, Наташа Романова.

Тони обновляет статус.

Его первое обновление: «Эй, я строю новый костюм Железного Человека», следующее — «Я собираюсь поставить на него палку для селфи, потому что эгоисты потрясающие, о да». И затем он публикует еще одно обновление: «Палка для селфи сломалась. Возвращаюсь к чертежной доске, обратно в мою лабораторию».

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

Но у друзей есть свои друзья, а у тех — свои обновления и т.п.

Так мы приходим к тому, что называется Big Data.

Потому что Big Data — это нечто, слишком большое для размещения JSON этих данных на слайде PowerPoint. Пусть это будет моим определением.

Мы реализовали поддержку статусов и их обновлений. И тут звонит телефон: «Ваш API забил весь наш канал… опять!», «Ваш API перегружает базу данных. Опять. Я говорил, нам нужно было использовать PHP… (ранее в PHP вы никогда не слышали о таких проблемах, правда?)»

Как мы это исправим? Что мы будем делать, чтобы решить эту проблему? Мы опять разделим наши данные. Вместо того, чтобы возвращать весь связанный с отдельной записью граф, мы предложим ссылки. Мы уже обсуждали, как использовать ссылки для движения вперед / назад. Теперь расширим эту идею.

self — указывает на профайл, который вы смотрите, потому что вы можете уходить от него по разным маршрутам и хотели бы иметь возможность быстро вернуться обратно (это обычная практика для подобных систем). Также вы можете быстро получить доступ к friends, photos и updates — друзьям, фотографиям и обновлениям.

Давайте также попробуем запросить фото:

Кто-то оставил к этой фотографии комментарии:

Давайте запросим фото 1345:

И здесь тоже есть чьи-то комментарии:

И снова звонит телефон: «Я должен сделать 50 вызовов API, чтобы просто выдать 1 страницу. ». «Наш веб-сервер упал из-за того, что IIS-логи заполнили диск C: (у нас никогда не было таких проблем с PHP)» — действительно, это одна из самых распространенных причин падения сервисов.

Что мы будем делать?

Мы взяли большой объем данных, который вызывал проблемы, и мы его разделили. И теперь небольшие данные вызывают уже другие проблемы.

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

Развертывание ресурсов — аналогичная идея для гипермедиа API. Таким образом мы можем запросить профиль Железного человека и развернуть его обновления.

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

Код, который это делает, — модуль Nancy:

Мы переходим к ProfileModules в нашем приложении. Для тех из вас, кто не работал с Nancy, отмечу, что здесь есть замечательная функция — словарь для каждого из HTTP-методов — GET, PUT, POST, DELETE.

Мы получаем объект с динамическим аргументом, который будет включать все, что соответствует шаблону маршрута. Далее есть метод, который нам нужно вызвать.

Он берет имя пользователя, идет в db.loadProfile и возвращает профиль.

Что мы хотим сделать, чтобы добавить гипермедиа? Добавить сюда подборку ссылок. Но мы не можем, потому что db.loadProfile тянет нас назад — мы не можем добавить в нее ссылки по разным корпоративным причинам. Так что мы хотим добавить ссылки, не изменяя базу данных.

Представляю крутейший фрагмент кода, который я когда-либо получал со Stackoverflow. Нашу проблему решит вызов метод ToDynamic:

Это метод расширения, встроенный в C#. Он принимает объект, а затем использует рефлекшн. Он оборачивает его в Expandable объект, который является базовым динамическим типом в C#. Далее мы используем отражение, чтобы получить все свойства изначального объекта. Для каждого из этих свойств мы переходим в словарь и добавляем к нему имя и значение свойства. А затем мы возвращаем расширенный объект (динамический).

Для чего нам это? Возьмем все, что мы вытащили из базы данных, и вызовем на нем ToDynamic. Теперь эти объекты открыты, потому что они динамические. Мы можем использовать любые дополнительные классы и методы. Все это будет разрешено в рантайме. Мы можем поставить self, photos, updates.

Повторюсь, к строго типизированной разработке корпоративного программного обеспечения C# мы подходим с другого конца, превращаясь в JSON. Это очень хороший пример использования двух разных парадигм моделирования программных систем.

Итак, что мы получаем:

Таков первый шаг: мы создали эти инструмент гипермедиа-навигации. Вы можете увидеть лучшего друга Железного Человека. Но мы не реализовали развертывание.

Мы подошли к моменту, когда процесс создания REST-системы внезапно вышел за рамки спецификации. Нет ни одного RFC или иного документа, который говорил бы, как следует реализовывать развертывание ресурсов. Есть много разных подходов. Но важна сама проблематика, а не фактический код. Поэтому в своем примере мы сделаем простейшую вещь, которая будет работать. Я собираюсь разобрать строку входящего запроса. Поскольку мы используем Nancy, все динамично до тех пор, пока вы не пожелаете иного.

Переведем его в строку (поскольку string unnullable, это безопасно). Далее я собираюсь сказать: «Если строка не пустая и содержит friends тогда включаем в динамичный профиль больше вещей».

И теперь, переключаясь обратно на API Explorer, мы видим результаты развертывания:

и когда мы добавим expand=friends, список друзей будет развернут.

Теперь у нас есть профиль Железного Человека. У нас есть его друзья, фотографии, обновления. Но нам нужно заработать немного денег.

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

Мы запускаем код в продакшн, и снова звонит телефон: «Попытка обновления статуса у Тони Старка вызвала конфликт»:

Это потому, что Тони Старк летает в своем костюме, и у него есть его часы Apple с GPS, поэтому его широта и долгота постоянно обновляются. И к тому времени, как вы обновили состояние, данные устарели.

Логично, что вы недовольны: почему вам приходится засовывать в PUT весь профайл, только чтобы обновить координаты?

Раньше я упоминал, что такое происходит, когда разработка выходит за рамки спецификации. Существует несколько различных способов, которыми мы можем решить эту проблему. Один из них — реализация правила: если выполняется PUT, содержащий только один заполненный элемент, не надо удалять все остальное. В этом случае можно просто обновить одно поле:

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

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

Однако с таким подходом вы получите массивный API. У вас будет очень много конечных точек. Это означает, что вам потребуется много гипермедиа, чтобы объяснить людям, какие из конечных точек доступны.

Существует альтернатива — HTTP-метод PATCH. Он очень крутой и мощный, но плохо документированный.

Метод PATCH запрашивает применение к ресурсу, идентифированному как Request URI, набор изменений, описанных в самом запросе. Набор изменений представляется в формате, названном «patch document» (идентифицирован как медиа-тип).

Т.е. если вы хотите изменить некий объект на сервере, вы можете отправить запрос PATCH.

Как описать необходимые изменения? Документация (здесь: «PATCH Method for HTTP» — http://tools.ietf.org/html/rfc5789) говорит, что вы должны прислать описание изменений. Как это реализовать? Зависит от вас.

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

Вот один из способов сделать это.

Мы на рабочей станции Linux. Мы скачаем, запустим его, чтобы получить patch-файл, и затем закачаем необработанный patch.

Здесь мы будем использовать альтернативный Content-type (x в данном случае означает, что это расширенный тип).

Это понимает наш сервер, и наш клиент. Мы можем скачать JSON, определить разницу «до» и «после», и отправить дельту.

Существуют потрясающие библиотеки, которые дают вам гораздо большую степень контроля, например, Json-patch. Она позволяет вам описать набор операций, которые будут применяться к некоторому ресурсу.

Таким образом мы могли бы реализовать, например, такие сценарии: заменить статус, затем — добавить нового пользователя в друзья и переместить нового друга вверх списка.

Последнее, что мы рассмотрим сегодня, — это наша собственная вариация того, как сделать HTTP-patch.

Мы собираемся исправить conferences/dotnext/

Мы используем альтернативный Content-Type — epic.selfie+png. В соответствии со стандартом все, что мы делаем, — описываем изменения. Мы собираемся сделать это фото, а затем описать изменения. И мы отправим его на сервер, и сервер ответит «202 принято». Я думаю, этот ответ нужно заменить на «вызов принят», потому что, на мой взгляд, у DOTNEXT действительно крутая поддержка.

Если вам понравился этот материал от Дилана, на нашей ноябрьской конференции DotNext 2017 Moscow он затронет еще одну любопытную тему — Life, liberty and the pursuit of APIness: the secret to happy code. В этом новом докладе он подскажет как сделать так, чтобы ваш код оставлял улыбки на лицах пользователей.

Разумеется, Дилан будет не единственным выступающим. Также вас наверняка заинтересуют:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *