RESTful API-обработка вложенных отношений
Предположим, я создаю API для обработки встреч. Прием состоит из врача, пациента и набора забот.
Если я хочу создать встречу, как должны выглядеть данные по почте? Обратите внимание, что только встреча будет создана с помощью этого запроса. Записи о враче, пациенте и заботах уже существуют в базе данных.
У меня есть 2 варианта:
Короткий
{
doctor_id: 8,
patient_id: 4,
cares_ids:
[1,7]
}
Более длинный
{
doctor: {
id: 8,
name: 'Dr James Brown',
phone: '107-102-304',
address: '16th avenue'
},
patient: {
id: 4,
name: 'Mr Elvis',
pathology: 'Blah Blah.'
},
cares:
[
{
id: 1,
name: 'Dental cares'
},
{
id: 7,
name: 'Back pain'
}
]
}
Коротышка чувствует себя чище, так как мы не посылаем бесполезные данные, такие как имя и адрес и т. д. Но второй кажется более естественным / семантическим в моем интерфейсном коде.
Например, в моем приложении мне нужно было бы только сделать:
appointment.doctor = selected_doctor
// Instead of doing
appointment.doctor_id = selected_doctor.id
Существуют ли какие-либо успокаивающие лучшие практики для такого рода случаев?
1 ответ:
На самом деле, вы столкнулись с проблемой отношений. OData предоставляет решение этой проблемы под названием "Свойства навигации". Возможно, это может дать вам некоторые подсказки на пути к исправлению этой проблемы. Вы можете посмотреть на эти ссылки для получения более подробной информации: http://www.odata.org/getting-started/basic-tutorial/ и http://www.odata.org/getting-started/advanced-tutorial/
На самом деле, здесь есть несколько вопросов:
- конструируйте представление вы хотите иметь при получении назначения
- проектирование представления для создания или обновления встречи
- создайте представление для назначения (однократная мощность - "врач" и "пациент") / добавления и удаления (многократная мощность - "забота") ссылки на прием (например, врач)
Я думаю, что полное представление, которое вы даете в своем вопросе, соответствует тому, что вы ожидаете получить при получении встречи, т. е. данные отношений, как врач, пациент и заботы.
Такие подсказки не все необходимы, чтобы связать назначение с другими элементами, такими как врач и пациент. Важны только идентификаторы. Я думаю,что вы могли бы иметь другое представление для создания назначения. На этом уровне достаточно установки ссылки на элемент. Так что вы могли бы somethinhg так:
POST /appointments { doctor-ref: http://.../doctors/8, patient-ref: http://.../patients/4, cares-ref: [ http://.../cares/1, http://.../cares/7 ] }
Или
POST /appointments { doctor@metadata.ref: http://.../doctors/8, patient@metadata.ref: http://.../patients/4, cares@metadata.ref: [ http://.../cares/1, http://.../cares/7 ] }
Таким же образом вы можете определить дополнительные ресурсы, чтобы иметь возможность обновлять их ссылки после встречи создавались без отправки всего контента. Мы могли бы представить себе что-то вроде этого:
Единичная мощность
PUT /appointments/<appointmentid>/doctor { doctor@metadata.ref: http://.../doctors/8 }
Множественная мощность
POST /appointments/<appointmentid>/cares { metadata.ref: http://.../cares/8 } DELETE appointments/<appointmentid>/cares { metadata.ref: http://.../cares/8 }
Вы можете заметить, что вы также можете выбрать не извлекать все данные о встрече для встречи (если это что-то интересное для вас). Вот различные представления, которые вы могли бы имейте:
Полный
{ doctor: { id: 8, name: 'Dr James Brown', phone: '107-102-304', address: '16th avenue' }, patient: { id: 4, name: 'Mr Elvis', pathology: 'Blah Blah.' }, cares: [ { id: 1, name: 'Dental cares' }, { id: 7, name: 'Back pain' } ] }
}
Parial со ссылками / ссылками
{ doctor@metadata.ref: http://.../doctors/8, patient: { id: 4, name: 'Mr Elvis', pathology: 'Blah Blah.' }, cares@metadata.ref: [ http://.../cares/1, http://.../cares/7 ] }
Или
{ doctor@metadata.ref: http://.../doctors/8, patient: { id: 4, name: 'Mr Elvis', pathology: 'Blah Blah.' }, cares: [ { id: 1, name: 'Dental cares' }, { id: 7, name: 'Back pain' } ] }
}
Эта функция соответствует в OData параметру запроса
$expand
.Вы можете посмотреть на эту ссылку: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/entity-relations-in-odata-v4 см. разделы "получение связанных сущностей", " создание связи между Сущности"и" удаление связи между сущностями". Это может дать подсказки для вашего представления.
Последняя часть вопроса связана с тем, как построить представление (например, для создания). Я не знаю точно, какую технологию вы используете, но в Java вы можете сделать что-то подобноеappointment.doctor = selected_doctor
и немного адаптировать сериализацию ваших объектов, чтобы создать что-то подобноеdoctor@metadata.ref: http://.../doctors/8
из экземпляра Doctor. Например, с Jackson2 , это называется custom сериализатор (см. Эту ссылку http://www.baeldung.com/jackson-custom-serialization например).Надеюсь, это поможет вам, Тьерри