Skip to content

DELETE to unlink one entity from another in a @ManyToMany association requires use of plain Entity ID, contrary to stated HAL principals [DATAREST-752] #1124

Open
@spring-projects-issues

Description

@spring-projects-issues

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}

See https://github.com/spring-projects/spring-data-rest/blob/master/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java#L357

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions