2013-12-01 2 views
2

Предположим, у меня есть ресурс (скажем, класс), у которого есть-много ресурсов Студента.REST, как правильно обращаться с отношениями

Class 
    id: 1 
    name: A 
    subject: Maths 

Student 
    name: Foo 
    surname: Bar 
    class: [?] 

У меня есть 2 сценария для решения проблемы.

[1]: Включить новый студент

В этом случае лучшим решением было бы добавить идентификатор класса и опубликовать ресурс как

Student 
    name: Foo 
    surname: Bar 
    class: 1 

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

[2]: Список Студентов, каждый со своим классом. Например:

Student Name | Student Surname | Student Class | Class Subject 
Foo1   Bar    A    Math 
Foo2   Bar    A    Math 
Foo3   Bar    B    Science 

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

  • (а) студенты нагрузки, с идентификатором класса, а также данные класса нагрузки в отдельный вызов
  • (б) студенты нагрузки, с внедренными данными класса

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

Students: [ 
    {name: Foo1, surname: Bar, class: 1}, 
    {name: Foo2, surname: Bar, class: 1}, 
    {name: Foo3, surname: Bar, class: 2}, 
] 

случая (б) представляется более целесообразным, так как мои студенты будут выглядеть

Students: [ 
    {name: Foo1, surname: Bar, class: {id:1, name: A, subject: Maths}}, 
    {name: Foo2, surname: Bar, class: {id:1, name: A, subject: Maths}}, 
    {name: Foo3, surname: Bar, class: {id:2, name: B, subject: Science}}, 
] 

Если я выбираю (а), я в порядке со сценарием [1], и у меня над головой с сценарий [2] (дополнительные вызовы для заполнения данных класса).

Если я выбираю (b), я в порядке со сценарием [2], но у меня проблемы с представлением сценария ресурса для сценария [1], так как я должен опубликовать полный ресурс класса в полезной нагрузке, например:

Student 
    name: Foo 
    surname: Bar 
    class: {id:1, name: B, subject: Science} 

Вопрос1: Какой был бы наилучший подход?

Вопрос2: Можете ли вы указать какое-либо хорошее чтение об этом?

== EDIT ==

Question3: Что такое не RESTful в выше?

+1

Это не вопросы о REST. Можете ли вы придумать более подходящие теги? –

+0

Ухм, почему бы и нет? я спрашиваю о правильном подходе отдыха для представления ресурсов – brazorf

+0

Итак, какой тип медиа вы определяете для представления указанных ресурсов? Какие отношения ссылок вы собираетесь использовать? Это вопросы, которые относятся к архитектуре REST-стиля. Вы, кажется, задаете вопросы о том, как отправлять данные по партиям по проводам, что хорошо ... но на самом деле это не имеет никакого отношения к REST. На самом деле вы можете утверждать, что использование идентификаторов, которые не являются URL-адресами, не является RESTful вообще. –

ответ

0

Корпус A кажется лучше.

  • Ваш студент хранит внешнего ключа к классу он посещает.
  • Обновление информации о классе легко, поскольку ученики хранят только внешний ключ (например,нет необходимости каскадировать обновления для всех студенческих объектов)

Предлагаю вам изучить старомодный relational database design. Даже если вы их не используете, вы узнаете многое о данных.

0

Используя ваш пример, вот как я могу это сделать, используя JSON и HAL.

Корневая страница:

Запрос:

GET/HTTP/1.1 
Host: example.com 

Ответ:

200 OK 
Content-Type: application/hal+json 

{ 
    "_links": { 
    "self": { "href": "/" }, 
    "students": { "href": "/students" }, 
    "classes": { "href": "/classes" }, 
    "students-with-classes": { "href": "/students?expand" }, 
    } 
} 

Создание нового студента будет документально на students связи с помощью размещения в условии HREF. Предположительно, я бы раньше следил за отношением ссылки classes, чтобы получить ссылку на класс A, чтобы я мог включить ее при добавлении пользователя.

Запрос:

POST /students HTTP/1.1 
Content-Type: application/json 

{ 
    name: "Foo", 
    surname: "Bar", 
    class-link: "/classes/1" 
} 

Ответ:

201 Created 
Location: http://example.com/students/10 

Листинг сбора студентов (после students-with-classes отношений);

Запрос:

GET /students?expand HTTP/1.1 

Ответ:

200 OK 
Content-Type: application/hal+json 

{ 
    "_links": { 
    self: { href: "/students" } 
    }, 
    "_embedded": { 
    "students": [ 
     { 
     "_links": { 
      "self": { "href": "/students/1" }, 
      "classes": [ { "href": "/classes/1", "title": "A" } ] 
     }, 
     "name": "Foo1", 
     "surname": "Bar" 
     }, 
     { 
     "_links": { 
      "self": { "href": "/students/2" }, 
      "classes": [ { "href": "/classes/1", "title": "A" } ] 
     }, 
     "name": "Foo2", 
     "surname": "Bar" 
     }, 
     { 
     "_links": { 
      "self": { "href": "/students/3" }, 
      "classes": [ { "href": "/classes/2", "title": "B" } ] 
     }, 
     "name": "Foo3", 
     "surname": "Bar" 
     } 
    ], 
    "classes": [ 
     { 
     "_links": { 
      "self": { "href": "/classes/1" } 
     }, 
     "name": "A", 
     "subject": "Math" 
     }, 
     { 
     "_links": { 
      "self": { "href": "/classes/2" } 
     }, 
     "name": "A", 
     "subject": "Science" 
     } 
    ] 
    } 
} 

Пару вещей отметить:

  • I POST общие application/json данные, но получить application/hal+json. Представления не обязательно должны быть одинаковыми в каждом направлении.
  • Я использую URI как идентификатор ресурса для класса, на который ссылается, а не искусственный внешний идентификатор. Такой идентификатор может быть быть частью этого URI, но клиент никогда не должен делать это предположение.
Смежные вопросы