We're building a RESTful web service similiar to the spring.io guide "Accessing JPA Data with REST". To reproduce the sample outputs below, it suffices to add a ManyToOne-Relation to Person as follows:
// ...
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
@ManyToOne
private Person father;
// getters and setters
}
A GET request after adding some sample data yields:
{
"firstName" : "Paul",
"lastName" : "Mustermann",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
},
"father" : {
"href" : "http://localhost:8080/people/1/father"
}
}
}
But, given Paul's father is stored with ID 2, our desired result would be the canonical url for its relation:
// ...
"father" : {
"href" : "http://localhost:8080/people/2"
}
// ...
This of course will cause problems if father is null on some persons (OK, this does not make much sense here... ;)), but in this case we would like to not render the link in JSON at all.
We already tried to implement a ResourceProcessor to achieve this, but it seems that by the time the processor is called the links are not populated yet. We managed to add additional links pointing to the desired canonical url, but failed to modify the somehow later added links.
Question: Is there a generic approach to customize the link generation for all resources?
To clarify our need for canonical URLs: We use the SproutCore Javascript framework to access the RESTful web service. It uses an "ORM-like" abstraction of data sources for which we've implemented a generic handler of the JSON output Spring produces. When querying for all persons, we would need to send n*(1+q) requests (instead of just n) for n persons with q relations to other persons to sync them to the client side data source. This is because the default "non-canonical" link contains absolutely no information about a father being set or the father's id. It just seems that this causes a huge amount of unnecessary requests which could be easily avoided if the initial response would contain a little more information in the first place.
Another solution would be to add the father's id to the relation, e.g.:
"father" : {
"href" : "http://localhost:8080/people/1/father",
"id" : 2
}