spring-projects / spring-projects/spring-hateoas
Traverson: Allow access of intermediate resources when traversing relations
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.1k
- Forks
- 476
- PR merge metrics
- No merged PRs in 30d
Description
When using Traverson, i can only retrieve the resource at the end of the traversal. It is often useful to retrieve the intermediate objects.
For instance i have CREDENTIALS, which are linked to an IDENTITY, which has a (main) CONTACT which has some ROLEs.
For a credential, i want to retrieve the identity and its contacts roles.
This gives me the contact roles, but there is no way to get at the identity.
Traverson t = new Traverson(new URI("http://127.0.0.1:8090/"), MediaTypes.HAL_JSON);
t.setRestOperations(template);
Map<String, Object> params = new HashMap<>();
params.put("name", "V6UqkSG8");
params.put("type", "myType");
String contactUuid = t.follow("credentials", "search", "byNameAndType", "$_embedded.credentials[0]._links.identity.href", "mainContact", "roles")
.withTemplateParameters(params).<String> toObject(String.class);
I can retrieve both this way, but's it's ugly.
Traverson t = new Traverson(new URI("http://127.0.0.1:8090/"), MediaTypes.HAL_JSON);
t.setRestOperations(template);
Map<String, Object> params = new HashMap<>();
params.put("name", "V6UqkSG8");
params.put("type", "myType");
String identity = t.follow("credentials", "search", "byNameAndType", "$_embedded.credentials[0]._links.identity.href")
.withTemplateParameters(params).toObject(String.class);
LinkDiscoverer linkDiscoverer = new HalLinkDiscoverer();
Link contactLink = linkDiscoverer.findLinkWithRel("mainContact", identity);
t = new Traverson(new URI(contactLink.getHref()), MediaTypes.HAL_JSON);
t.setRestOperations(template);
String contactRoles = t.follow("roles").<String> toObject(String.class);
A few options
- Traverson could be stateful, retrieving an object and remembering it to allow a subsequent follow to resume from that resource
String identity = t.follow("credentials", "search", "byNameAndType", "$_embedded.credentials[0]._links.identity.href").toObject(String.class);
String contactRoles = t.follow("mainContact", "roles").toObject(String.class);
- Traverson could store everything for later retrieval
String contactRoles = t.follow("credentials", "search", "byNameAndType", "$_embedded.credentials[0]._links.identity.href", "mainContact", "roles").toObject(String.class);
String contact = t.retrieveFromTraverse("mainContact").toObject(String.class);
String identity = t.retreiveFromTraverse("$_embedded.credentials[0]._links.identity.href").toObject(String.class);
- Traverson could optionally return some sort of intermediate object to hold state
TraversonState identityTS = t.follow("credentials", "search", "byNameAndType", "$_embedded.credentials[0]._links.identity.href").toState();
String identity = identityTS.toObject(String.class);
String contactRoles = identityTS.follow("mainContact", "roles");
All much clearner looking than
String identity = t.follow("credentials", "search", "byNameAndType", "$_embedded.credentials[0]._links.identity.href")
.withTemplateParameters(params).toObject(String.class);
LinkDiscoverer linkDiscoverer = new HalLinkDiscoverer();
Link contactLink = linkDiscoverer.findLinkWithRel("mainContact", identity);
t = new Traverson(new URI(contactLink.getHref()), MediaTypes.HAL_JSON);
t.setRestOperations(template);
String contactRoles = t.follow("roles").<String> toObject(String.class);
PS. It would be nice if spring-data-rest would return a single object from a query method whoose signature returns a single entity to avoid all the "$_embedded.credentials[0]._links.identity.href" stuff.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Traverson follow(...).toObject(...) flow and the LinkDiscoverer/HalLinkDiscoverer usage shown in the issue. Compare the proposed stateful, stored-intermediate, and intermediate-state approaches, then define and test one supported API for retrieving intermediate resources while continuing traversal.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100