spring-data-rest icon indicating copy to clipboard operation
spring-data-rest copied to clipboard

PUT ignores linkable resources [DATAREST-1118]

Open spring-projects-issues opened this issue 8 years ago • 4 comments
trafficstars

Clive Cox opened DATAREST-1118 and commented

As discussed in this StackOverflow question PUT ignores linkable resources in LinkedAssociationSkippingAssociationHandler:

if (associationLinks.isLinkableAssociation(association)) {
     return;
}

However, PATCH works.

Is there a reason for this?


No further details from DATAREST-1118

spring-projects-issues avatar Aug 18 '17 13:08 spring-projects-issues

Oliver Drotbohm commented

Yes. Links to associated resources are not part of the actual payload but metadata elements and we need to preserve symmetry between what's returned with GET and what is accepted with POST.

{
  "someKey" : "someValue",
  "_links" : {
    "customer : { "href" : "…" }
  }
}

_links is a metadata field defined by HAL. It's moved there because we explicitly expose resources for links to other aggregates so that the relationship is managed via those.

Imagine you'd just take this payload and PUT it back to the server. If the linkable associations were not ignored, this would wipe the relationship, as _links is ignored as it's not part of the resource state but metadata

spring-projects-issues avatar Aug 18 '17 21:08 spring-projects-issues

Clive Cox commented

Thanks for the explanation. Maybe I can provide an example that still confuses me.

If I have 2 classes Foo and Bar and in Bar I have a JPA relationship @OneToOne Foo myFoo; Then I can POST a Foo to http://myapp/foos and get its link, e.g., http://myapp/foos/1

I can then POST a Bar to http://myapp/bars with content {"myFoo":"http://myapp/foos/1"} and get its link back, e.g., http://myapp/bars/1

I can then POST a new Foo and get its link, e.g. http://myapp/foos/2

I can then PATCH the Bar with {"myFoo":"http://myapp/foos/2"} on the URL http://myapp/bars/1 and this works and updates the link

However, if I had PUT {"myFoo":"http://myapp/foos/2"} on the URL http://myapp/bars/1 this gets ignored.

I assume I am missing something because to me the "_links" metadata is different from a field like "myFoo".

In my use of this project I would rather update via PUT/PATCH a resource in a single call. At present I just use PATCH. If this is the solution I am fine with that.

spring-projects-issues avatar Aug 19 '17 09:08 spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-projects-issues avatar Jan 07 '21 10:01 spring-projects-issues

I also ran into this issue. For me it seems that it now only works with POST. Posting

{
    "firsName": "X",
    "lastName": "Y",
    "ownBooks": ["http://localhost:8080/api/books/5"]
}

to http://localhost:8080/api/persons will create a new User and correctly assigning the owned books. But using PUT or PATCH on an existing user like http://localhost:8080/api/persons/1 the ownBooks property ist ignored. Is this a Bug or a Feature that its still working with POST? Is there a way to update the owned books by PUT or PATCH to http://localhost:8080/api/persons/1 or does ist require two requests? One to http://localhost:8080/api/persons/1 and another to http://localhost:8080/api/persons/1/ownBooks

jason076 avatar Feb 03 '23 13:02 jason076