RESTful сервис архитектуры вопрос - PullRequest
5 голосов
/ 08 июня 2010

Этот вопрос больше касается стратегии архитектуры сервисов, мы создаем большую веб-систему, основанную на остальных сервисах на стороне сервера. И в настоящее время мы пытаемся создать некоторые внутренние стандарты, которым необходимо следовать при разработке услуг отдыха.

Некоторые запросы возвращают список сущностей, например, давайте рассмотрим, есть ли у нас сервис поиска галерей изображений: / gell_all_galeries, возвращающий следующий ответ:

<galleries>
   <gallery>
      <id>some_gallery_id</id>
      <name>my photos</name>
      <photos>
          <photo>
                <id>123</id>
                <name>my photo</name>
                <location>http://mysite/photo/show/123</location>
                ......
                <author>
                     <id>some_id</id>
                     <name>some name</name>
                     .......
                <author>
          </photo>
          <photo> ..... </photo>
          <photo> ..... </photo>
          <photo> ..... </photo>
          <photo> ..... </photo>
    </photos>
  </gallery>
  <gallery> .... </gallery>
  <gallery> .... </gallery>
  <gallery> .... </gallery>
  <gallery> .... </gallery>
</galleries>

Как вы видите здесь, ответ довольно большой и тяжелый, и не всегда нам нужен такой глубокий информационный уровень. Обычное решение - использовать или http://ru.wikipedia.org/wiki/Atom элементов для каждой галереи вместо полных данных галереи:

<galleries>
   <gallery>
      <id>some_gallery_id</id>
      <link href="http://mysite/gallery/some_gallery_id"/>
   </gallery>
   <gallery>
      <id>second_gallery_id</id>
      <link href="http://mysite/gallery/second_gallery_id"/>
   </gallery>
  <gallery> .... </gallery>
  <gallery> .... </gallery>
  <gallery> .... </gallery>
  <gallery> .... </gallery>
</galleries>

Первый вопрос следующий: возможно, вместо этого мы даже не должны использовать и вводить типы, а просто использовать generic и для всех ресурсов, которые возвращают объекты списка:

 <list>
  <item><link href="http://mysite/gallery/some_gallery_id"/></item>
  <item><link href="http://mysite/gallery/other_gallery_id"/></item>
  <item>....</item>
</list>

И второй вопрос: после того, как пользователь попытается получить информацию о какой-то конкретной галерее, он будет использовать, например, ссылку http://mysite/gallery/some_gallery_id, что он должен видеть в результате?

Должно ли это быть:

   <gallery>
      <id>some_gallery_id</id>
      <name>my photos</name>
      <photos>
          <photo>
                <id>123</id>
                <name>my photo</name>
                <location>http://mysite/photo/show/123</location>
                ......
                <author>
                     <id>some_id</id>
                     <name>some name</name>
                     .......
                <author>
          </photo>
          <photo> ..... </photo>
          <photo> ..... </photo>
          <photo> ..... </photo>
          <photo> ..... </photo>
    </photos>
  </gallery>

или:

   <gallery>
      <id>some_gallery_id</id>
      <name>my photos</name>
      <photos>
          <photo><link href="http://mysite/photo/11111"/></photo>
          <photo><link href="http://mysite/photo/22222"/></photo>
          <photo><link href="http://mysite/photo/33333"/> </photo>
          <photo> ..... </photo>
    </photos>
  </gallery>

или

   <gallery>
      <id>some_gallery_id</id>
      <name>my photos</name>
      <photos>
          <photo>
               <link href="http://mysite/photo/11111"/>
               <author>
                    <link href="http://mysite/author/11111"/>
               </author>
           </photo>
          <photo>
               <link href="http://mysite/photo/22222"/>
               <author>
                    <link href="http://mysite/author/11111"/>
               </author>
           </photo>
          <photo>
               <link href="http://mysite/photo/33333"/>
               <author>
                    <link href="http://mysite/author/11111"/>
               </author>
           </photo>
          <photo> ..... </photo>
    </photos>
  </gallery>

Я имею в виду, если мы будем использовать ссылку вместо полной информации об объекте, как глубоко мы должны идти туда? Должен ли я показать автора внутри фотографии и т. Д.

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

Ответы [ 4 ]

3 голосов
/ 08 июня 2010

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

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

Оптимизация размера ответов может быть важна для производительности, но кэширование гораздо важнее .Отправка 0 байтов по проводам всегда более эффективна.

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

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

В создании нет ничего плохого:

/gallery/foo/quickview
/gallery/foo/detailedview
/gallery/foo/justlinks

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

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

Большинство людей, когда они начинают пользоваться службами REST, привыкли к мысли, что они могут предоставлять прямые application / xmlили application / json в качестве типа носителя.В некоторых специализированных случаях это полностью выполнимо, однако, когда вы начнете реализовывать больше ограничений REST, вы обнаружите, что универсальные форматы типов носителей ограничат преимущества, которые вы можете получить во многих случаях .На данный момент, не беспокойтесь об этом, просто знайте, что всегда безопаснее выбрать «настоящий» тип носителя, такой как application / xhtml, RDF или Atom, и если вы выберете application / xml, вы можете столкнуться с трудностямипозже.

2 голосов
/ 08 июня 2010

Хорошая вещь, которую стоит рассмотреть, - это то, как вы собираетесь получать данные от клиентов.Если вы хотите, чтобы клиент получил целую кучу информации о многих фотографиях, тогда список только <photo href="..."/> может оказаться неоптимальным, поскольку клиент будет вынужден выполнить запрос GET для каждого ресурса фотографии, который ему нужен.информация о.

Я могу придумать пару интересных способов обойти это без предела.

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

GET http://www.example.com/photos?_fields=author,fileSize

Это может затем вернуть что-то вроде:

<photos href="/photos?_fields=author,fileSize">
    <photo href="/photos/15">
        <author href="/authors/2245"/>
        <fileSize>32MB</fileSize>
    </photo>
    ...
</photos>

В качестве альтернативы, вы можете упростить его, позволив клиенту указать какой-то максимум "свойство глубины;это немного более грубо, но может быть эффективно использовано.Например, если клиент указал глубину 2, вы бы вернули все под <gallery>, а также все дочерние элементы каждого <photo>.

GET /galleries?depth=2

Может вернуть что-то вроде:

<galleries>
  <id>22</id>
  <name>My Gallery</name>
  <!-- full gallery data -->
  <photos href="/photos?gallery=/galleries/22">
    <photo href="/photos/99">
      <id>99</id>
      <author href="/authors/4381"/><!-- href instead of including nested author data -->
      <fileSize>24MB</fileSize>
      <!-- full photo data -->
    </photo>
    ...
  </photos>
</galleries>

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

GET /photos?gallery=/galleries/59

Возможно возвращение:

<photos href="/photos?gallery=/galleries/59&_max=100&_first=100" next="/photos?gallery=/galleries/59&_max=100&_first=200" prev="/photos?gallery=/galleries/59&_max=100&_first=0" count="100" total="3528">
    ....
</photos>

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

В конечном итоге все зависит от того, как вы хотите, чтобы ваш сервер давал указание клиентам получать данные.Если вы не хотите, чтобы они делали GET для каждой фотографии, возможно, вы захотите предоставить им более удобные способы получения более глубоких данных.Но если вы считаете, что ваш сервер может справиться с приличной нагрузкой, и наряду с этим вы можете выполнить оптимизацию на стороне сервера (кэширование, использование 304 состояний и т. Д.), То просто вернуть поверхностные списки с href s немного проще.

1 голос
/ 10 июня 2010

Это действительно зависит от вашего сценария. Вы должны знать, как клиент будет использовать это, чтобы знать, как проектировать ваши Resource Proxies .

Я предлагаю вам не заблудиться в «перекрестке выбора». Просто перейдите к одной реализации, основанной на том, что вы предполагаете об использовании клиента. Посмотрите, как все это используется и ведет себя, затем отрегулируйте его, если это необходимо. Стирать. Промыть. Повторение. Сделай это постоянным бета-способом:)

0 голосов
/ 08 июня 2010

Вы всегда можете использовать атрибуты.

  <gallery id = "1" name = "Gallery 1">
      <photos>
          <photo id="1" link="http://mysite/photo/11111" />
          <photo id="2" link="http://mysite/photo/22222" />
          <photo id="3" link="http://mysite/photo/33333" />
      </photos>
  </gallery>

Или вы можете использовать JSON, я предпочитаю его, так как он проще и легче, чем XML.

{
    "gallery": {
        "id": "1",
        "name": "Gallery 1",
        "photos": [
            {
                "id": "1",
                "link": "http://mysite/photo/11111" 
            },
            {
                "photo": "2",
                "link": "http://mysite/photo/22222" 
            },
            {
                "photo": "3",
                "link": "http://mysite/photo/33333" 
            } 
        ] 
    } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...