Description
Marc Zampetti opened DATAREST-752 and commented
I think there is an issue with the current design of Spring Data Rest when it comes to utilizing associations between two Entities. The main issues I'm highlighting is that the HAL-based method of using links and link traversal to manage the state as implemented is not viable.
Let's say I have a simple User Management system that tracks Users (modeled with a User entity) and Groups (modeled with a Group) entity. Each entity can stand on its own, so there is never a parent-child relationship between them. Instead, there exists a @ManyToMany
link between each side.
In SDR, I can create the link between the two entities by making the request:
POST /users/{id}/groups
Using as the body of request the href of the Group object that I wish to associate, and a Content-Type of text/uri-list. See http://docs.spring.io/spring-data/rest/docs/2.4.2.RELEASE/reference/html/#_post_2
If I wish to see all of the Groups that a user currently is a member of, I call
GET /users/{id}/groups
And will get back the list of Group entities. But currently, the _links->self link will be the reference to itself of the form /groups/{id}, and not anything that is relative to the user I was searching for.
Now I want to remove the link between and User and the Group. The docs suggest using DELETE, but they are unclear as to exactly how to make that call. Looking at the code however, its clear from RepositoryPropertyReferenceControllerthat the way to do so is to call
DELETE /users/{id}/groups/{propertyId}
So this results in a deficiency in the design of SDR. If you have not enabled the exposeIds configuration item on the RestRepositoryConfig, then there is no easy way to determine what the {propertyId} is for the associated entity you wish to remove in the above DELETE call. You would be forced to parse the URI to determine that. And I cannot call
DELETE /users/{id}/groups
as that will remove all links between the given user and the groups, i.e. it removes the user from all groups.
One way to resolve this would be to make the 'self' link that is returned as a result of the
GET /users/{id}/groups
to be relative to that call, for example
/users/{id}/groups/{propertyId}
Then we could also create a 'group' link in this case to represent the entity itself. Or keep the 'self' link the same and have some other way to designate the relative link. Then the caller would have the info they need to be able to execute the DELETE that I am discussing.
Affects: 2.4.2 (Gosling SR2)
5 votes, 6 watchers