如何使用 HATEOAS 设置相关对象?

How to set a related object using HATEOAS?

我无法使用从 springboot 存储库生成的 HATEOAS link 使用 restful API。

考虑以下模型:

public class Order {
  private UUID id;
  private String orderNumber;
  private Location location;
}

public class Location {
  private String street;
  private String town;
}

为了便于阅读,我省略了任何样板代码,例如 getter、setter 和构造函数。

启动服务后,我创建了一个空的 Order,我可以这样查询:

>curl http://localhost:8080/orders/1

哪个returns:

{
  "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,它会 returns 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"
    }
  }
}

进入正题,我卡壳了。 我如何从 link LocationOrder None 我的尝试成功了。如果有任何建议,我将不胜感激。

到目前为止我试过:

1. PUT 对象

>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。 POST到link

>curl -XPOST http://localhost:8080/orders/1/location \
  -H 'Content-Type: application/json' \
  -d '{"street": "Bakerstreet 221B", "town": "London"}'

管理总结

>curl -XPUT http://localhost:8080/orders/1/location \
  -H "Content-Type: text/uri-list" \
  -d "http://localhost:8080/location/1"

详细说明

如果我调用带有 -I 标志和禁止方法的嵌套位置 uri,则会列出允许的方法。

>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

这意味着 url 上的 PUT 必须有效。把这个 url 和一个空的 body 放在一起会产生:

>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 以设置为 body.

>curl -XPUT http://localhost:8080/orders/1/location \
  -H "Content-Type: text/uri-list" \
  -d "http://localhost:8080/location/1"