Иерархия объектов Python и ресурсы REST? - PullRequest
1 голос
/ 30 сентября 2011

В настоящее время я сталкиваюсь с "архитектурной" проблемой в моем приложении Python (использующем Twisted), которое использует API REST, и я ищу обратную связь.

Внимание! длинный пост впереди!

Предположим, что следующий объект hiearchy:

class Device(object):
  def __init__():
    self._driver=Driver()
    self._status=Status()
    self._tasks=TaskManager()

  def __getattr__(self, attr_name):
    if hasattr(self._tasks, attr_name):
        return getattr(self._tasks, attr_name)
    else:
        raise AttributeError(attr_name)

 class Driver(object):
   def __init__(self):
     self._status=DriverStatus()

   def connect(self):
      """some code here""" 

   def disconnect(self):
     """some code here"""

 class DriverStatus(object):
   def __init__(self):
     self._isConnected=False
     self._isPluggedIn=False

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

/ отдых / окружающая среда

/ Остальное / окружающая среда / {ID}

/ Остальное / окружающая среда / {ID} / устройства / * * 1014

/ Остальное / окружающая среда / {ID} / устройства / {DeviceId} * * 1016

/ Остальное / окружающая среда / {ID} / устройства / {DeviceId} / водитель

/ Остальное / окружающая среда / {ID} / устройства / {DeviceId} / водитель / driverstatus

Я перешел несколько месяцев назад с «грязного» мыла типа Api на REST, но я не уверен, как справиться с чем-то вроде дополнительной сложности:

  1. Распространение ресурсов REST / типов носителей : например, вместо того, чтобы иметь только ресурс Device , у меня теперь есть все эти ресурсы:

    • Устройство
    • DeviceStatus
    • Driver
    • DriverStatus

    Хотя все это имеет смысл с точки зрения Resfull, нормально ли иметь много субресурсов, которые каждый сопоставляет с отдельным классом python?

  2. Отображение ядра приложения с расширенным набором методов в API Rest-Full : в Rest ресурсы должны быть существительными, а не глаголами : существуют ли хорошие правила / советы для разумного определения набор ресурсов из набора методов? (Наиболее полный пример, который я нашел до сих пор, кажется, эта статья )

  3. Логика API, влияющая на структуру приложения : должна ли логика API приложения хотя бы частично направлять некоторую внутреннюю логику, или это хорошая практика для применения разделения интересов? То есть, должен ли я иметь промежуточный уровень «ресурсных» объектов, которые должны связываться с ядром приложения, но что не не отображает один в один с классами ядра?

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

Это довольно длинные вопросы, поэтому спасибо за ваше терпение, и любые указания, отзывы и критика приветствуются!


до S.Lott:

  • Под "слишком фрагментированными ресурсами" я имел в виду множество различных субресурсов, которые в основном все еще применяются к одному и тому же объекту на стороне сервера

  • Для «соединения»: Так что же тогда будет модифицированная версия ресурса «DriverStatus»? Я считаю, что соединение всегда существует, поэтому используется «PUT», но разве это плохо, учитывая, что «PUT» должен быть идемпотентным?

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

    - Дело в том, что сейчас базовые «объекты реального мира», как вы их называете, имеют смысл для меня как для остальных ресурсов / наборов ресурсов, и ими правильно манипулируют через POST, GET, UPDATE, DELETE, но я с трудом осмысливая подход «Отдых» к вещам, которые я не инстинктивно воспринимаю как «Ресурсы».

Ответы [ 2 ]

4 голосов
/ 01 октября 2011

Правило 1. REST касается объектов.Не методы.

REST-ресурсы слишком фрагментированы

False.Всегда ложно.Ресурсы REST независимы.Они не могут быть «слишком» фрагментированными.

вместо того, чтобы иметь только ресурс устройства, у меня теперь есть все эти ресурсы:

Device DeviceStatus Driver DriverStatus

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

На самом деле, они не имеют смысла.Отсюда твой вопрос.

Устройство это вещь./ rest / environment / {id} / devices / {deviceId}

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

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

считать соединение существующим всегда, поэтому использование«PUT», но разве это плохо, учитывая, что «PUT» должен быть идемпотентным?

Соединения не всегда существуют.Они могут приходить и уходить.

Хотя реляционная база данных может иметь таблицу ассоциаций «многие ко многим», которую вы можете ОБНОВИТЬ, это особый особый случай, который на самом деле не имеет особого смысла вне мира администраторов баз данных.

Связь между двумя объектами RESTful редко бывает отдельной.Это атрибут каждой из вещей RESTful.

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

Не имея каких-либо полезных фактов, я предполагаю, что вы подключаете устройства к драйверам, и есть какие-то [Device]<-[Driver Status]->[Driver] отношения.Соединение между устройством и драйвером может быть отдельным ресурсом RESTful.

Это также может быть атрибут устройства или драйвера, который на самом деле не имеет отдельного видимого ресурса RESTful.

[Снова.Некоторые фреймворки, такие как Django-Piston, упрощают раскрытие базовых классов.Однако это может быть не всегда уместно.]

Существуют ли хорошие правила / советы для интеллектуального определения набора ресурсов из набора методов?

Да.Не делай этого.Ресурсы не являются методами.В значительной степени это так.

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

Состоящие объекты не являются изначально злыми, но их необходимо критически исследовать.В некоторых случаях PUT для изменения статуса объекта, возможно, должен был быть POST для добавления в историю объекта.«Текущее» состояние - это последнее, что отправлено.

Также.

Вам не нужно тривиализировать каждый ресурс как класс вещей.Вы можете иметь ресурсы, которые являются коллекциями.Вы можете поместить довольно сложный документ в составной (по сути Facade ) «ресурс».Этот сложный документ может подразумевать несколько операций CRUD в базе данных.

Вы уходите от простого RESTful.Ваш вопрос остается намеренно темным.«Ядро приложения, богатое методами» не имеет большого значения.Без конкретных примеров это невозможно представить.

Логика API, влияющая на структуру приложения

Если они чем-то отличаются, вы, вероятно, создаете ненужную, бесполезную сложность.

Является ли хорошей практикой применение разделения интересов?

Всегда.Зачем спрашивать?

большая часть этого, кажется, происходит из-за моей путаницы в том, как сопоставить довольно богатый метод api с Rest-Full, где ресурсы должны быть существительными, а не глаголами: так, когда разумно считать элемент отдыхом? "ресурс "?

Ресурс определяется вашей проблемной областью.Обычно это что-то материальное.Методы (как в «API-интерфейсе с богатыми методами», как правило, не имеют значения. Это операции CRUD (создание, получение, обновление, удаление). Если у вас есть что-то, что по сути не является CRUD, вам нужно ОСТАНОВИТЬ кодирование. ОСТАНОВИТЬ написание кода иПереосмыслите API, чтобы сделать его похожим на CRUD.

CRUD - Create-Retrieve-Update-Delete сопоставляет с PEST-GET-PUT-DELETE REST. Если вы не можете преобразовать проблемный домен в эти термины, остановитеськодирование. Прекратите кодирование, пока не доберетесь до правил CRUD.

Мне нужно иметь возможность отображать список доступных типов драйверов (т.е. имена классов, а не экземпляр драйвера) в клиенте: это будет означать созданиееще один ресурс, такой как "DriverTypes"?

Правильно. Они уже являются частью вашего проблемного домена. У вас уже определен этот класс. Вы просто делаете его доступным через REST.


Вот в чем дело. Проблемная область имеет объекты реального мира. У вас есть определения классов. Это материальные вещи. REST передает состояние этих материальных вещей.

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

«Ассоциация» всегда видна из обоих реальных ресурсов RESTful.Один ресурс может иметь ссылку, подобную внешнему ключу, которая позволяет клиенту выполнять RESTful-выборку другого связанного объекта.Или ресурс может иметь коллекцию других связанных объектов, и один GET получает объект и коллекцию связанных объектов.

В любом случае, реальные ресурсы RESTful - это то, что доступно.Отношения просто подразумеваются.Даже если это физическая таблица базы данных «многие ко многим» - это не значит, что должно быть открыто.[Снова.Некоторые фреймворки позволяют легко разоблачить все.Это не всегда хорошо.]

0 голосов
/ 01 октября 2011

Вы можете представить часть пути /rest с объектом Site, но environments в пути должно быть Resource.Оттуда вы должны сами управлять иерархией в render_* методах environments.Полученный вами объект request будет иметь атрибут postpath, который даст вам остаток пути (т. Е. После /rest/environments).Вам придется проанализировать id, определить, задан ли в пути devices, и, если это так, передать оставшуюся часть пути (и запрос) в коллекцию устройств.К сожалению, Twisted не примет это решение за вас.

...