Прежде всего, обновление закусочной и ланч-бокса должно быть сделано в одном запросе. Не попадайтесь в ловушку попыток совершать транзакции через API REST.
Прежде чем мы перейдем к вашему конкретному вопросу, давайте заложим основы того, как клиент мог бы взаимодействовать с вашим сервисом, приводя к вашему вопросу.
Клиент всегда должен запускаться с URL-адреса корневого сервиса.
GET /DiningService
Content-Type: application/vnd.sample.diningservice+xml
200 OK
<DiningService>
<Link rel="diners" href="./diners"/>
<Link rel="lunchboxes" href="./lunchboxes"/>
<Link rel="foods" href="./foods"/>
</DiningService>
Я не знаю, как ваши пользователи будут взаимодействовать с клиентским программным обеспечением, но давайте предположим, что сначала нам нужно определить, кто будет есть. Мы можем получить список посетителей из поиска в ответе ссылки с rel = "diners" и перейти по этой ссылке.
GET /DiningService/diners
Content-Type: application/vnd.sample.diners+xml
200 OK
<Diners>
<Diner Name="Frank">
<Link rel="lunchbox" href="./Frank/lunchbox"/>
</Diner>
<Diner Name="Bob">
<Link rel="lunchbox" href="./Bob/lunchbox"/>
</Diner>
</Diners>
Возвращается список посетителей. Я решил создать пользовательские типы носителей для простоты, но вам может быть лучше использовать что-то вроде каналов Atom для этих списков.
Клиент должен идентифицировать Фрэнка как посетителя, и теперь мы хотим получить доступ к его ланч-боксу. Правила нашего нестандартного типа мультимедиа гласят, что ссылка на ланч-бокс Фрэнка
можно найти в элементе ссылки с rel = "lunchbox".
Мы получаем этот URL из ответного документа и следуем за ним.
GET /DiningService/Frank/lunchbox
Content-Type: application/vnd.sample.lunchbox+xml
200 OK
<Lunchbox>
<Link rel="diner" href="/DiningService/Frank"/>
<Food Name="CheeseSandwich" NutritionPoints="10">
<Link rel="eat" Method="POST" href="/DiningService/Frank?food=/DiningService/Food/CheeseSandwich"/>
</Food>
<Food Name="CucumberSandwich" NutritionPoints="15">
<Link rel="eat" Method="POST" href="/DiningService/Frank?food=/DiningService/Food/CucumberSandwich"/>
</Food>
</Lunchbox>
Что мы получаем, так это еще один пользовательский тип мультимедиа, определяющий содержимое ланч-бокса и ссылки, описывающие, что мы можем сделать с этим ланч-боксом. Как только клиент выберет еду для еды, мы можем определить URL-адрес, по которому нужно перейти, найдя ссылку с rel = "eat" и следуя этому URL. В данном случае это пост.
POST /DiningService/Frank?food=/DiningService/Food/CucumberSandwich
Content-Type: None
200 OK
Я не особо задумывался о том, как лучше всего структурировать этот URL, потому что, если я передумаю на следующей неделе и сделаю это
<Link rel="eat" Method="POST" href="/DiningService/Frank/Mouth?food=/DiningService/Food?id=759"/>
или даже
<Link rel="eat" Method="POST" href="/DiningService/Food/CheeseSandwich?eatenBy=Frank"/>
это действительно не имеет значения для клиента, потому что он продолжит искать ссылку с rel = "eat" и будет следовать URL. Вы выбираете любую структуру URL, наиболее удобную для выбранной вами веб-структуры. Структура URL принадлежит серверу, и вы должны иметь возможность изменять ее всякий раз, когда это мало или совсем не влияет на клиента.
Если вы воспользуетесь этим подходом, вы можете перестать беспокоиться о том, чтобы найти идеальный URL. Это искусственное понятие «URL-адрес RESTful» сделало больше для предотвращения изучения REST людьми, чем когда-либо SOAP!