RESTFful/Resource Oriented Design
Предположим, что у меня есть трехуровневая иерархия, состоящая из школы, учеников и классов.
Если я выставляю студента в качестве ресурса, мой вопрос заключается в том, должен ли я всегда возвращать родительскую "школу" и "классы" детей вместе с этим учеником или должен быть парм, который пользователь включает, чтобы указать на это. Возможно, что-то вроде & deep = True?
Или, с другой стороны, если пользователь получает ученика, и он хочет школу, он должен сделать ПОЛУЧЕНИЕ на школьном ресурсе, а также, если он хочет всех классов, которые принимает ученик, он должен сделать GET на ресурсе классов?
Я стараюсь, чтобы дизайн был несколько открытым для неизвестного будущего пользователя, а не для кодирования только для удовлетворения наших текущих требований.
Спасибо,
Нил Уолтерс
Ответы
Ответ 1
Я думаю, вам следует избегать думать о классах как о субресурсе или атрибуте ученика. Академический класс - это больше, чем просто временной график по расписанию учеников; у него есть инструктор, учебный план и т.д., все из которых, возможно, необходимо будет закодировать в какой-то момент.
Как я вижу, справедливы следующие соотношения:
- школы имеют ноль или более студентов.
- В школах есть ноль или более классов
- У студентов есть нулевые или более классы
- классы имеют ноль или более студентов
(Вы могли бы также тривиально расширить их с учителями/инструкторами, если ваши требования включали такую информацию.)
Кроме того, каждый из указанных типов ресурсов будет иметь любое количество атрибутов, помимо простых связей между ними.
Учитывая это, я думаю, вам нужна структура URL-адреса примерно так:
-
http://example.com/lms/schools
= > список школ
-
http://example.com/lms/schools/{school}
= > информация об одной школе
-
http://example.com/lms/schools/{school}/students
= > список студентов
-
http://example.com/lms/schools/{school}/students/{student}
= > информация об одном студенте
-
http://example.com/lms/schools/{school}/students/{student}/courses
= > список курсов (как ссылки, а не полные ресурсы) учащийся зачислен в
-
http://example.com/lms/schools/{school}/courses
= > список курсов
-
http://example.com/lms/schools/{school}/courses/{course}
= > информация об одном курсе
-
http://example.com/lms/schools/{school}/courses/{course}/students
= > список студентов (как ссылки, а не полные ресурсы), зачисленных в курс
Ответ 2
Если вы думаете о дизайне ресурсов больше в том, как вы думаете о дизайне пользовательского интерфейса, проблема становится проще. Нет причин, по которым вы не можете вернуть подмножество школьной информации в представлении ресурса Студента, а также вернуть ссылку на полное представление о ресурсе школы, если пользователь хочет увидеть больше.
Мне кажется полезным использовать интерфейс REST, как пользовательский интерфейс для машин, а не уровень доступа к данным. С этим мышлением не проблема дублировать информацию в разных представлениях ресурсов.
Я знаю, что есть много людей, которые пытаются обработать REST, как DAL, но они - те же самые люди, которые расстраиваются, когда выясняют, что вы не можете делать транзакции через интерфейс RESTful.
Другими словами, создайте свой API так, как если бы вы разработали веб-сайт (но без каких-либо хороших вещей), а затем создайте клиента, который может сканировать сайт для необходимой ему информации.
Ответ 3
Я полагаю, что добавление параметров запроса для оптимизации доставки является разумным. Я мог бы сделать его еще более общим и использовать include=<relation>
. Это может быть расширено для всех типов. Обратите внимание, что
вы можете использовать несколько включений: .../student/<id>?include=school&include=student
назначит список [school, student]
параметру include
. Это также позволит использовать общую схему, которая может быть полезной и для других ресурсов.