Closed sadam21 closed 2 years ago
Thanks for asking, I will think about it.
sorry for not reacting in time, I am a little busy right now. I did not forget it and will try to respond before Christmas.
OK, thank you!
Hi Adam,
to get the information for the relationships, you can use the @JsonApiRelationships annotation, like
@Data
@Entity
@NoArgsConstructor
class Person {
@Id
@GeneratedValue
@JsonIgnore
private Long id;
//attributes
private String name;
private Integer age;
// relationships
@OneToOne
@JsonApiRelationships("city")
@JsonIgnore
private City city;
@OneToMany
@JsonApiRelationships("jobs")
@JsonIgnore
private List<Job> jobs;
Then a person can be serialized to (you have to use the builder for serialization)
{
"data": {
"type": "persons",
"attributes": {
"name": "Kai",
"age": 56
},
"relationships": {
"city": {
"data": {
"id": "2",
"type": "cities"
}
},
"jobs": {
"data": [
{
"id": "1",
"type": "jobs"
}
]
}
}
}
}
If you want to patch a person, send a PATCH request like
{
"data": {
"type": "persons",
"attributes": {
"name": "Kay",
"age": 57
},
"relationships": {
"city": {
"data": {
"id": "4",
"type": "cities"
}
},
"jobs": {
"data": [
{
"id": "7",
"type": "jobs"
}
]
}
}
}
}
If you want to distinguish between a value that should explicitly be set to null and a value that is not set at all in the patch body, one solution could be to use a special marker identifier like <<<null>>>
in your patch body. Then your controller could react to this value and update the DTO's value to null.
I have created a little demo with your example (including serialization and patch method), you can download it at https://my.hidrive.com/share/ylcmjtbywn Password is patch-demo
Please re-open if you have further questions or contact me via email kai@toedter.com.
What is the recommended way to handle PATCH request for entities with several attributes and relationships? What should DTOs look like?
I saw example https://github.com/toedter/spring-hateoas-jsonapi/blob/master/lib/src/test/java/com/toedter/spring/hateoas/jsonapi/support/WebMvcMovieController.java .
We have to differentiate usecases:
Our solution: We've introduced for our use case
OptionalProperty<T>
interface which is "wrapper" around entity property. Its implementationNoneProperty
represents property which isn't sent in PATCH andSomeProperty<T>
(property was sent).We have our
OptionalPropertyDeserializer
registered to object mapper. It works fine for attributes but we have problem with relationships because ourOptionalProperty
is generic non-collection so it's skipped inJsonApiEntityModelDeserialize::convertToRepresentationModel
(https://github.com/toedter/spring-hateoas-jsonapi/blob/master/lib/src/main/java/com/toedter/spring/hateoas/jsonapi/JsonApiEntityModelDeserializer.java#L84).If
OptionalProperty
works for you I can help with implementation to library (also with any other solution).Thank you!
Adam