Статьи

Введение в язык приложений гипертекста (HAL)

Принципы архитектурного стиля REST были изложены доктором Роем Филдингом в его  диссертации  «Архитектурные стили и проектирование сетевых программных архитектур». Одним из основных принципов стиля является то, что приложения REST должны управляться  гипермедиа , то есть изменение состояния приложения или, другими словами, переход от одного ресурса к другому, должен выполняться по ссылкам. Обоснование этого принципа заключается в том, что все возможные операции с ресурсом могут быть обнаружены без необходимости какой-либо внеполосной документации, и если некоторые URI изменяются, нет необходимости менять клиента, поскольку ответственность за генерацию URI лежит на сервере. вставьте их в представления. Этот принцип также называется гипермедиа как двигатель состояния приложения (HATEOAS ).

В то время как тезис дает указание использовать гиперссылки в представлениях ресурсов,  Hypertext Application Language  (HAL) является одним из возможных рецептов создания представлений дизайна со ссылками. В частности, он описывает, как проектировать представления JSON, хотя есть и аналог XML. Наше обсуждение будет ограничено только разновидностью JSON.

Что касается медиа-типа HAL, то в настоящее время, согласно  документу , его медиа-тип — application / vnd.hal + json. Это как-то связано с тем, что существует несколько деревьев регистрации, то есть сегментов для типов медиа, с различными  требованиями . Примеры включают стандарты, поставщика и личные деревья. Дерево стандартов не имеет префикса для типа носителя. Последние два имеют vnd и prs соответственно. Когда HAL перемещается в дерево стандартов, его именем типа контента будет application / hal + json. В настоящее время  пример приложения,  предоставленного автором HAL Майком Келли, создает application / json в своем заголовке Content-Type, поэтому точный тип носителя не так важен для нашего обсуждения.

Существует удобный способ определить, является ли API RESTful или нет. Так называемая Richardson Maturity Model (РММ) был представлен Леонард Ричардсон в своем 2008 QCon  говорить  и позже  популяризировал  Мартина Фаулера. Модель вводит четыре уровня зрелости API, начиная с уровня 0, так что на уровне два каждый ресурс не только идентифицируется своим собственным URI, но и все операции с ресурсами выполняются с использованием методов HTTP, таких как GET, PUT и т. Д. Если API находится на Уровень 3 можно рассматривать как RESTful. С точки зрения RMM HAL помогает обновить API уровня 2 до уровня 3, в котором используются гипермедиа.

Чтобы запачкать руки с помощью HAL, давайте обсудим простой API каталога книг, где пользователь может просматривать книги; этот API может быть частью более крупного приложения, такого как книжный магазин, но его миссия — быть только каталогом книг. Данные для нашего API могут быть скопированы с amazon.com. Некоторые URI и методы перечислены ниже.

метод    URI     Описание
ПОЛУЧИТЬ    / книги     Показать все книги
ПОЛУЧИТЬ    / книги / {ID}     Показать детали книги с идентификатором id
ПОЛУЧИТЬ    / авторы / {ID}     Показать детали для автора с идентификатором id

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

{
    "Title":"RESTful Web APIs",
    "Price":"$31.92",
    "Paperback":"408 pages",
    "Language":"English"
}

Самое время добавить несколько ссылок. Первым кандидатом является ссылка на сам объект, как это рекомендовано спецификацией HAL. Для добавления ссылок в HAL есть зарезервированное ключевое слово _links. Первым его символом является подчеркивание, которое было выбрано для того, чтобы зарезервированные ключевые слова отличались от имен свойств объектов в представлениях, хотя не все имена, начинающиеся с подчеркивания, являются зарезервированными. Фактически, _links — это имя объекта, свойства которого описывают значение конкретной ссылки. Значения свойств должны содержать URI, а также могут содержать некоторые другие полезности.

Исправлены ли имена свойств? Ну, некоторые есть, и список  здесь , но можно добавить ее собственный, как будет описано позже. Возвращаясь к нашей собственной ссылке, в списке есть одноименный тип отношений, и наш объект book может выглядеть как фрагмент ниже.

{
    "_links":{
        "self":{
            "href":"/book/123"
        }
    },
    "Title":"RESTful Web APIs",
    "Price":"$31.92",
    "Paperback":"408 pages",
    "Language":"English"
}

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

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

{
    "_links":{
        "self":{
            "href":"/book/123"
        },
        "http://booklistapi.com/rels/authors":[
            {
                "href":"/author/4554",
                "title":"Leonard Richardson"
            },
            {
                "href":"/author/5758",
                "title":"Mike Amundsen"
            },
            {
                "href":"/author/6853",
                "title":"Sam Ruby"
            }
        ]
    },
    "Title":"RESTful Web APIs",
    "Price":"$31.92",
    "Paperback":"408 pages",
    "Language":"English"
}

Перейдя по  ссылке http://booklistapi.com/rels/authors, можно прочитать дополнительную информацию об этом типе отношений. Как видно из приведенного выше фрагмента, свойства объекта ссылки не ограничиваются href, который является единственным обязательным, есть еще несколько свойств, включая title, понятный человеку идентификатор. Некоторые другие примеры — это type для типа media и hreflang для подсказки о языке представления. Еще одно замечание, касающееся таможенных отношений, заключается в том, что в использованной выше форме он выглядит немного многословно. У HAL есть способ справиться с этой проблемой, и он называется Compact URI или  CURIE .

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

{
    "_links":{
        "self":{
            "href":"/book/123"
        },
        "curries":[
            {
                "name":"ns",
                "href":"http://booklistapi.com/rels/{rel}",
                "templated":true
            }
        ],
        "ns:authors":[
            {
                "href":"/author/4554",
                "title":"Leonard Richardson"
            },
            {
                "href":"/author/5758",
                "title":"Mike Amundsen"
            },
            {
                "href":"/author/6853",
                "title":"Sam Ruby"
            }
        ]
    },
    "Title":"RESTful Web APIs",
    "Price":"$31.92",
    "Paperback":"408 pages",
    "Language":"English"
}

Мы использовали свойство name объекта link для предоставления ключа для выбора объекта, который позже используется в имени нашего пользовательского типа отношения — ns: авторы. Затем мы использовали шаблонный URI, который можно развернуть, чтобы получить полный URI, как и в предыдущем примере, для доступа к документации. Одно дополнительное свойство является шаблоном, которое по умолчанию имеет значение false, но при использовании шаблонов URI должно быть установлено значение true. Еще одно место, где можно использовать шаблоны, — это ссылки, которые позволяют выполнять поиск, в результате чего поисковые термины добавляются в шаблон для получения полного URI.

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

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

{
    "_links":{
        "self":{
            "href":"/author/4554"
        },
        "curries":[
            {
                "name":"ns",
                "href":"http://booklistapi.com/rels/{rel}",
                "templated":true
            }
        ]
    },
    "_embedded":{
        "ns:books":[
            {
                "_links":{
                    "self":{
                        "href":"/books/123"
                    }
                },
                "Title":"RESTful Web APIs",
                "Price":"$31.92"
            },
            {
                "_links":{
                    "self":{
                        "href":"/books/366"
                    }
                },
                "Title":"RESTful Web Services",
                "Price":"$79.78"
            },
            {
                "_links":{
                    "self":{
                        "href":"/books/865"
                    }
                },
                "Title":"Ruby Cookbook",
                "Price":"$34.35"
            }
        ]
    }
}

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

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

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

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

Рекомендации

  1. JSON Связь с HAL

  2. HAL — язык гипертекстовых приложений

  3. Язык гипертекстовых приложений JSON

  4. Интервью с создателем HAL Майком Келли