REST Медиа тип взрыва - PullRequest
45 голосов
/ 19 мая 2009

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

Одна маленькая часть нашего приложения выглядит так:

коллекция-оф-collections-> коллекций-оф-изделия-> предметов

Т.е. верхний уровень - это коллекция коллекций, и каждая из этих коллекций снова является коллекцией предметов.

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

application/vnd.mycompany.collection-of-collections+xml
application/vnd.mycompany.collection-of-items+xml
application/vnd.mycompany.item+xml

Более того, поскольку каждый элемент имеет 8 атрибутов, которые могут быть прочитаны и записаны по отдельности, это приведет к появлению еще 8 типов носителей. например один такой тип носителя для атрибута «value» элемента будет:

application/vnd.mycompany.item_value+xml

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

Мои вопросы:

  1. Я что-то не так делаю, имея такое огромное количество типов медиа?
  2. Каков альтернативный метод проектирования, чтобы избежать такого взрыва типов носителей?

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

Ответы [ 6 ]

32 голосов
/ 19 мая 2009

Один из подходов, который уменьшил бы количество требуемых типов мультимедиа, заключается в использовании типа мультимедиа, определенного для хранения списков других типов мультимедиа. Это может быть использовано для всех ваших коллекций. Обычно списки, как правило, имеют согласованный набор поведения. Вы можете свернуть свой собственный список vnd.mycompany.resourcelist или использовать что-то вроде коллекции Atom .

Что касается конкретных представлений ресурсов, таких как vnd.mycompany.item, то, что вы можете сделать, во многом зависит от характеристик вашего клиента. Это в браузере? вы можете сделать код загрузки? Ваш клиент - богатый пользовательский интерфейс, или это клиент обработки данных?

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

Помните, медиа-тип - это ваш контракт, если ваше приложение должно определить множество контрактов с клиентом, пусть будет так.

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

30 голосов
/ 11 июля 2009

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

Недавно я наткнулся на утверждение " тип носителя для помощи в настройке механизма гипермедиа, схема для структуры " в записи блога Джим Уэббер . Затем я нашел эту презентацию Йена Робинсона из Thoughtworks. Эта презентация является одной из лучших, с которыми мне довелось познакомиться, и которая дает четкое представление о ролях и обязанностях типов медиа и языков схем (вся презентация - удовольствие, и я настоятельно рекомендую всем). Особенно обратите внимание на слайды под названием «Вы выбрали приложение / xml, вы b st rd». и «Пользовательские типы носителей». Ян четко объясняет различные роли схем и типов носителей. Короче говоря, это мой вывод из презентации Иана:

Описание типа мультимедиа включает модель обработки, которая определяет элементы управления гипермедиа и определяет, какие методы применимы к ресурсам этого типа. Определение элементов управления гипермедиа означает «Как мы идентифицируем ссылки?» в XHTML ссылки идентифицируются на основе тегов, и RDF имеет различную семантику для одного и того же. Следующая вещь, которую помогают идентифицировать типы медиа, - какие методы применимы к ресурсам данного типа медиа? Хорошим примером является спецификация ATOM (application / atom + xml), которая дает очень подробное описание элементов управления гипермедиа; они говорят нам, как определяется элемент ссылки? и что мы можем ожидать, чтобы иметь возможность делать, когда мы разыменовываем URI, чтобы он фактически что-то говорил о методах, которые мы можем ожидать применить к ресурсу. Структурная информация о представлении ресурса представляет собой NOT часть или NOT , содержащуюся в описании типа носителя, но предоставляется как часть соответствующей схемы фактического представления, т.е. выиграна спецификация типа носителя ' Не обязательно диктовать что-либо о структуре представления.

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

Надеюсь, это поможет.

7 голосов
/ 07 июня 2013

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

Чтобы люди понимали и использовали ваш API REST-ish, им необходимо понимать , означающее данных. Существуют API, в которых типы мультимедиа рассказывают большую часть истории; например если у вас есть API для преобразования текста в речь, тип носителя для ввода текста - text / plain, а тип носителя для вывода - audio / mp4, то, возможно, кто-то, знакомый с предметом, может это сделать. Текстовый вход, аудио выход, вероятно, достаточно для продолжения в этом случае.

Но многие API не могут передать большую часть своего значения только с помощью типа носителя. Допустим, у вас есть API, который обрабатывает авиабилеты. Входы и выходы будут в основном данными. Типы медиа на входе и выходе каждого API могут быть application / json или application / xml, поэтому тип медиа не передает много информации. Итак, вы бы посмотрели на отдельные поля во входах и выходах. Может быть, есть поле под названием «цена». Это в долларах или пенни? USD или какая-то другая валюта? Я не знаю, как пользователь ответил бы на эти вопросы без (а) очень описательных имен, таких как "price_pennies_in_usd", или (b) документации. Не говоря уже о форматных соглашениях. Предоставляется ли номер счета с тире или без, буквы должны быть заглавными и т. Д. Не существует стандартного типа носителя, определяющего эти проблемы.

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

Но это совсем другое, когда клиент (или фактически разработчик / пользователь, стоящий за клиентом) должен понимать семантику данных. ДАННЫЕ НЕ МЕДИА . Невозможно объяснить данные во всех их реальных значениях и тонкостях, кроме их документирования. Это вариант использования данных.

Чрезмерно академическое определение REST работает в случае использования СМИ. Он не работает и должен быть дополнен не чистыми, но полезными вещами, такими как документация, для других случаев использования.

1 голос
/ 21 мая 2009

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

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

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

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

Другими словами, такой язык, как xsd, позволяет вам вводить тип мультимедиа для поддержки одного из нескольких корневых элементов. Нет ничего плохого в том, что application / vnd.acme.humanresources + xml описывает XML-документ, который может принимать любой из них или быть корневым элементом.

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

1 голос
/ 19 мая 2009

Вы используете тип носителя для передачи сведений о ваших данных, которые должны храниться в самом представлении. Таким образом, у вас может быть только один тип носителя, скажем «application / xml», и тогда ваши XML-представления будут выглядеть так:

<collection-of-collections>
    <collection-of-items>
        <item>
        </item>
        <item>
        </item>
    </collection-of-items>
    <collection-of-items>
        <item>
        </item>
        <item>
        </item>
    </collection-of-items>
</collection-of-collections>

Если вы хотите отправить слишком много данных, замените JSON на XML. Другой способ сэкономить на написанных и прочитанных байтах - использовать кодировку gzip, которая сокращает расходы примерно на 60-70%. Если у вас нет сверхвысокой производительности, один из этих подходов должен работать для вас. (Для повышения производительности вы можете использовать очень краткие строки, созданные вручную, или даже перейти к пользовательскому двоичному протоколу TCP / IP.)

Редактировать Одна из ваших проблем заключается в том, что:

грубое [представление] означает, что в итоге я буду передавать ненужные данные по проводам, когда на самом деле клиенту нужно только прочитать или записать один атрибут элемента

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

Вы должны взять копию RESTful Web Services от Ричардсона и Руби , которая является действительно превосходной книгой о том, как проектировать веб-службы REST, и объясняет вещи гораздо яснее, чем я мог. Если вы работаете на Java, я настоятельно рекомендую инфраструктуру RESTlet , которая очень точно моделирует концепции REST. * Рой Филдинг USC диссертация определение принципов REST также может быть полезным.

0 голосов
/ 20 мая 2009

Если вы не собираетесь регистрировать эти типы мультимедиа, вы должны выбрать один из существующих типов mime вместо того, чтобы пытаться создавать свои собственные форматы. Как говорит Джим, application / xml или text / xml или application / json работает для большей части того, что передается в REST-дизайне.

В ответ на Даррел вот полный текст Роя . Разве вы не пытаетесь определить типизированные ресурсы, создавая свои собственные типы пантомимы?

Суреш, почему HTTP + POX не успокаивает?

...