Я решил отлавливать EmptyResultDataAccessException и ничего с ними не делать. Я думаю, что если вы попытаетесь удалить ресурс, который не существует, результат будет таким же, как если бы он существовал до удаления. То есть ресурс перестанет существовать. Существовал ли он раньше или нет не имеет значения. Кроме того, я мог бы написать deleteOrder(), чтобы вернуть ResponseEntity, установив тело в null и код состояния HTTP NOT FOUND.
Единственное, на что следует обратить внимание в методе deleteOrder(), это то, что он аннотирован @ResponseStatus, чтобы гарантировать, что HTTP-статус ответа равен 204 (NO CONTENT). Нет необходимости передавать какие-либо данные ресурса обратно клиенту для ресурса, который больше не существует, поэтому ответы на запросы DELETE обычно не имеют тела и, следовательно, должны сообщать код состояния HTTP, чтобы клиент знал, что не стоит ожидать никакого содержимого.
Ваш Taco Cloud API начинает обретать форму. Клиентский код теперь может легко использовать этот API для отображения ингредиентов, принятия заказов и отображения недавно созданных тако. Но есть кое-что, что вы можете сделать, что сделает ваш API еще проще для клиента. Давайте посмотрим, как вы можете добавить hypermedia в Taco Cloud API.
6.2 Добавление hypermedia
API, который вы создали до сих пор, довольно прост, но он работает, пока клиент, который его использует, знает схему URL API. Например, клиент может быть жестко закодирован, чтобы знать, что он может получить список недавно созданных тако, выполнив запрос GET для /design/recent. Аналогично, он должен понимать, что он может добавить идентификатор любого taco из полученного перечня в /design, чтобы получить URL для этого конкретного taco.
Использование жестко закодированных шаблонов URL и манипулирование строками распространено среди клиентского кода API. Но представьте на мгновение, что произойдет, если изменится схема URL API. Жестко закодированный клиентский код будет иметь устаревшее понимание API и, таким образом, будет не корректен. Жесткое кодирование URL-адресов API и использование строковых манипуляций с ними делает клиентский код хрупким.
Гипермедиа как движок состояния приложения, или HATEOAS, является средством создания API с функционалом самоописания, в которых ресурсы, возвращаемые из API, содержат ссылки на связанные ресурсы. Это позволяет клиентам перемещаться по API с минимальным пониманием URL-адресов API. Вместо этого он понимает взаимосвязи между ресурсами, обслуживаемыми API, и использует свое понимание этих взаимосвязей для обнаружения URL-адресов API по мере их прохождения.
Например, предположим, что клиент должен был запросить список недавно разработанных тако. В необработанном виде, без гиперссылок, список последних тако будет получен в клиенте с JSON, который выглядит следующим образом (для краткости все, кроме первого тако в списке, вырезаны):
[
{
"id": 4,
"name": "Veg-Out",
"createdAt": "2018-01-31T20:15:53.219+0000",
"ingredients": [
{"id": "FLTO", "name": "Flour Tortilla", "type": "WRAP"},
{"id": "COTO", "name": "Corn Tortilla", "type": "WRAP"},
{"id": "TMTO", "name": "Diced Tomatoes", "type": "VEGGIES"},
{"id": "LETC", "name": "Lettuce", "type": "VEGGIES"},
{"id": "SLSA", "name": "Salsa", "type": "SAUCE"}
]
},
...
]
Если клиент желает получить или выполнить какую-либо другую HTTP-операцию над конкретным тако, ему необходимо знать (с помощью жесткого кодирования), что он может добавить значение свойства id к URL-адресу, путь которого - /design. Аналогично, если бы он хотел выполнить операцию HTTP над одним из ингредиентов, ему нужно было бы знать, что он может добавить значение свойства id ингредиента к URL-адресу, путь которого равен /ingredients. В любом случае ему также необходимо добавить префикс к этому пути с http: // или https: // и имя хоста API.
Напротив, если API включен с гипермедиа, API будет описывать свои собственные URL-адреса, освобождая клиента от необходимости жестко кодировать эти знания. Тот же список недавно созданных тако мог бы выглядеть как следующий список, если бы были вставлены гиперссылки.
Листинг 6.3. Список тако-ресурсов с гиперссылками
{
"_embedded": {
"tacoResourceList": [
{
"name": "Veg-Out",
"createdAt": "2018-01-31T20:15:53.219+0000",
"ingredients": [
{
"name": "Flour Tortilla", "type": "WRAP",
"_links": {
"self": { "href": "http://localhost:8080/ingredients/FLTO" }
}
},
{
"name": "Corn Tortilla", "type": "WRAP",
"_links": {
"self": { "href": "http://localhost:8080/ingredients/COTO" }
}
},
{
"name": "Diced Tomatoes", "type": "VEGGIES",