Как отправить глубоко вложенный ресурс с помощью Restful API (HATEOAS)
Скажем, у меня есть ресурс приложения, который содержит контактные данные ресурсов, а контактные данные содержат адреса ресурсов.
Например.
Application
--> Name
--> Application Amount
--> Application Contacts
--> --> Contact 1
--> --> --> Address
--> --> Contact 2
--> --> --> Address
При выполнении POST to Application я создаю корневое приложение. Для всех подресурсов, таких как Контакты приложений, я делаю POST для создания Контакта 1 и т. Д.
У меня вопрос: приложение = отправить куда-то на обработку, но я не хочу подавать его до того, как все заполнено, то есть все дочерние ресурсы.
So the order of submission
1) Create Application Resource --> POST /Application --> Get ID
2) Create Contact 1 Resource --> POST /Application/id/Contacts --> Get ID
3) Create Contact 1 Address Resource --> POST /Application/id/Contacts/id/Addresses
4) Create Contact 2 Resource --> POST /Application/id/Contacts --> Get ID
5) Create Contact 2 Address Resource --> POST /Application/id/Contacts/id/Addresses
6) DECIDE TO SUBMIT HERE <--- ?? HOW?
мистифицировать
3 ответа
Ваш дизайн не RESTful. Ваши ресурсы, вероятно, сопоставления 1-к-1 с вашими бизнес-объектами? Я не советую этого делать, потому что это раскрывает внешний вид вашей модели домена для внешнего мира, что может вызвать проблемы с версиями. Это также делает такие проблемы сложнее, чем они должны быть - хотя вы можете использовать среду REST, которая навязывает вам этот дизайн:-( .
Следует помнить, что ресурсы в REST являются абстрактными представлениями элемента вашей доменной модели, который вы хотите видеть во внешнем мире, и им вполне может потребоваться отображение и преобразование, прежде чем они могут быть преобразованы в объекты домена. Они могут быть сколь угодно сложными.
Я бы сказал, что решение здесь состоит в том, чтобы позволить POST создать приложение, а также создать контакты и их адреса. Затем клиент может либо предоставить URL-адреса для существующих контактов и адресов (которые сервер может разыменовать для объектов домена), либо необходимые сведения для создания новых в одном POST. Тогда ответственность за создание и связывание сущностей транзакционным способом ложится на сервер. Он просто возвращает ссылку на URL, который идентифицирует новое приложение. Если вам нужно знать URL-адреса для контактов, то вы повторно ПОЛУЧАЕТЕ приложение, и оно будет содержать их.
Предполагая JIME-тип MIME для вашего ресурса, начальный POST может выглядеть так:
{
Name: "Application name",
Amount: "123.00",
Contacts: [
{
Name: "Contact name",
Address: {
HouseNumber: "45",
StreetName : "Sesame Street"
}
}
]
}
Return: {href: “/Application/6789”}
GET для /Application/6789 будет возвращать что-то вроде:
{
Name: "Application name",
Amount: "123.00",
Contacts: [
{ mimeType: "application/vnd.com.myStuff.contact+json", href: "/Contact/203" }
]
}
Надеюсь, я правильно понял ваш вопрос. Дайте мне знать, если я пропустил суть и всегда могу вернуться с чем-то новым.
Таким образом, если все "подресурсы" уже созданы с шага 1 до шага 5. На каждом шаге должен быть возвращенный идентификатор для подтверждения успешного создания ресурса. Подобно,
POST /Application
Return: {appid: “/Application/id”}
Таким образом, как только POST шага 5 возвращается, последний ресурс создается. Затем следующим шагом является запуск приложения "обработка".
"Обработка заявки" может рассматриваться как ресурс, а бизнес-действия: "создать обработку" и "проверить результаты обработки"
Они могут быть смоделированы с использованием POST и GET соответственно на ресурсе "Processing".
Создать ресурс обработки
POST /Application/id/Processing
Return: {processingid: “/Application/id/Processing/id”}
Чтобы проверить ресурс обработки
GET /Application/id/Processing/id
Return: {processingid: “/Application/id/Processing/id”, <other info>}
Чтобы вернуть все приложение,
GET /Application/id
Return: {all info on the application including processing status as well…}
Надеюсь, это поможет.
Скорее всего, у вас будет какое-то поле состояния, чтобы указать, подана ли заявка или нет. В этом случае я бы предложил следующие два подхода:
1) Публикация на ресурсе приложения, в поле состояния которого указано правильное значение для указания вашего намерения:
POST /application/654321
status=submitted...
Вот цитата из Филдинга Диссертация:
"Компоненты REST выполняют действия с ресурсом, используя представление для захвата текущего или предполагаемого состояния этого ресурса и передачи этого представления между компонентами".
2) Опубликуйте приложение в определенной коллекции / представленных приложениях, которые вы также можете использовать для поиска в представленных приложениях с помощью GET:
POST /submittedapplications
id=654321...
Поскольку, скорее всего, существуют дополнительные этапы обработки помимо простого обновления ресурса приложения, следует использовать глагол POST, чтобы указать, что двойная отправка не подходит.
Кстати, оба подхода не являются взаимоисключающими, вы, безусловно, можете реализовать оба в одном и том же API.