Как установить связанный объект, используя HATEOAS?
Я не могу использовать успокоительный API со ссылками HATEOAS, сгенерированными из репозиториев Springboot.
Рассмотрим следующую модель:
public class Order {
private UUID id;
private String orderNumber;
private Location location;
}
public class Location {
private String street;
private String town;
}
Просто для удобства чтения я исключил любой стандартный код, такой как геттеры, сеттеры и конструкторы.
После запуска сервиса я создал пустой Order
, что я могу запросить как:
>curl http://localhost:8080/orders/1
Который возвращает:
{
"orderNumber": "ON 0815",
"_links": {
"self": {
"href": "http://localhost:8080/orders/1"
},
"location": {
"href": "http://localhost:8080/orders/1/location"
}
}
}
Теперь, если я позвоню curl http://localhost:8080/orders/1/location
, это возвращает HTTP 404 - Not found
Это разумно, потому что я еще этого не установил.
Затем я создаю Location
установить через HTTP POST
:
curl -XPOST http://localhost/8080/locations \
-H 'Content-Type: application/json' \
-d '{"street": "Bakerstreet 221B", "town": "London"}'
Служба отвечает:
{
"street": "Bakerstreet 221B",
"town": "London",
"_links": {
"self": {
"href": "http://localhost:8080/locations/1"
}
}
}
Теперь мы подошли к делу, я застрял на. Как мне связать Location
к Order
? Ни одна из моих попыток не сработала. Буду благодарен за любой совет.
Пока что попробовал:
1. Поставить объект
>curl -XPUT http://localhost:8080/orders/1 \
-H 'Content-Type: application/json' \
-d '{"orderNumber": "ON 0815", "_links": {"self": {"href": "http://localhost:8080/orders/1"}, "location": {"href": "http://localhost:8080/orders/1/location"}}}'
2. ЗАПИШИТЕ объект
>curl -XPATCH http://localhost:8080/orders/1 \
-H 'Content-Type: application/json' \
-d '{"_links": {"self": {"href": "http://localhost:8080/orders/1"}, "location": {"href": "http://localhost:8080/orders/1/location"}}}'
3. ПОСТ на ссылку
>curl -XPOST http://localhost:8080/orders/1/location \
-H 'Content-Type: application/json' \
-d '{"street": "Bakerstreet 221B", "town": "London"}'
1 ответ
Резюме управления
>curl -XPUT http://localhost:8080/orders/1/location \
-H "Content-Type: text/uri-list" \
-d "http://localhost:8080/location/1"
Подробное описание
Если я называю вложенное местоположение URI с -I
флаг и запрещенный метод, разрешенные методы перечислены.
>curl -I -XPOST http://localhost:8080/orders/1/location \
-H 'Content-Type: application/json'
HTTP/1.1 405
Allow: GET,PUT,PATCH,DELETE
Content-Length: 0
Date: Mon, 29 Oct 2018 08:59:19 GMT
Это означает PUT
на этом URL должен быть действительным. Помещение этого URL с пустым телом приводит к:
>curl -XPUT http://localhost:8080/orders/1/location \
-H 'Content-Type: application/json' \
-d '{}'
{"cause":null,"message":"Must send only 1 link to update a property reference that isn't a List or a Map."}
После поиска этого сообщения я обнаружил, что мой Content-Type
был неправ. Мне нужно использовать Content-Type: text/uri-list
и добавьте URL-адрес местоположения, чтобы установить в качестве тела.
>curl -XPUT http://localhost:8080/orders/1/location \
-H "Content-Type: text/uri-list" \
-d "http://localhost:8080/location/1"