Closed jiangchuan1220 closed 5 years ago
Using List makes it very simple to build hypermedia.
By building a link via linkTo(methodOn(MyController.class).createEntry()).withRel("create")
and then feeding it into Resources, we can leverage Java's "..." notation.
Imagine building a Map through a Java constructor call.
The truth is, we don't have to build the target mediatype. Internal types like Resources don't dictate that the output goes to HAL. Other mediatypes are possible (actually in the works once the affordances branch is complete) without binding the internal representation of body and links.
To be honest assuming that ResourceSupport maps 1-to-1 with HAL, SIREN, or whatever would be a faulty premise.
What is the problem of declare links as "Map" in ResourceSupport? Then the links type is consistent in API declare and real response. Currently the problem is that links is "List" in API declaration while in real response it is changed to "Map".
I just listed several reasons and you simply repeated your original question.
There are media types which output the links as a list not a map. Hence the API to build all the links is more important than one result type.
Actually, to match perfectly with HAL, which is a map of listed links, the proper type for ResourceSupprt.links should be Map<String, List<Link>>
. That would allow unpacking it perfectly for HAL.
{
"_links": {
"self": { "href": "/orders" },
"curies": [{ "name": "ea", "href": "http://example.com/docs/rels/{rel}", "templated": true }],
"next": { "href": "/orders?page=2" },
"ea:find": {
"href": "/orders{?id}",
"templated": true
},
"ea:admin": [{
"href": "/admins/2",
"title": "Fred"
}, {
"href": "/admins/5",
"title": "Kate"
}]
},
But not for Siren:
"links": [
{ "rel": [ "self" ], "href": "http://api.x.io/orders/42" },
{ "rel": [ "previous" ], "href": "http://api.x.io/orders/41" },
{ "rel": [ "next" ], "href": "http://api.x.io/orders/43" }
]
Siren has a list of links. Hence, altering the core structure of ResourceSupport.links doesn't appear likely, when to do so we would additionally be trading in Java 8 lists for Maps.
I see there are different kinds of links and it is difficult to summary them into one type. But the current solution has conflicts between the declaration and the actual response. I hope there would be a perfect solution for this issue in the future.
Please clarify what conflict you are seeing in what mediatype between ResourceSupport and the resulting output. If this a bug in link generation in HAL, I would appreciate you describing what it is.
Apart from that, I believe accumulating a List of Link objects is sufficient for support of HAL, HAL-FORMS, Uber, SIREN, and Collection+JSON.
In ResourceSupport, links are declared as List. While in response body, links are transform to Map by a customized jackson ObjectMapper. Why do not keep links the same type (either List or map) in both ResourceSupport and response body? I am asking this question because this mismatch can lead to some automatical API description generator (e.g., swagger) can not know the transform and considers the links to be array in response body.