What is the difference between withSelfRel() and withRel(...), and how do IanaLinkRelations fit in?
answer
- withSelfRel() == withRel(IanaLinkRelations.SELF)
- withRel(String) custom, withRel(LinkRelation) typed
- IanaLinkRelations = registered vocabulary (NEXT/PREV/FIRST/LAST)
- rel becomes _links key in HAL
- same rel twice → JSON array
basics
~10 swithSelfRel() sets the relation to 'self'. withRel(...) sets any other relation, by String ("orders") or by a LinkRelation constant. IanaLinkRelations provides the standard registered relation names like SELF, NEXT, PREV.
solid answer
~40 sEvery Link has a relation (rel) that names its meaning. withSelfRel() is a convenience for the very common 'self' relation — it equals withRel(IanaLinkRelations.SELF). withRel(...) attaches any other relation and is overloaded: withRel(String) for custom names like "orders", and withRel(LinkRelation) for typed constants. IanaLinkRelations (org.springframework.hateoas.IanaLinkRelations) is a class of constants for IANA-registered link relation types — SELF, NEXT, PREVIOUS/PREV, FIRST, LAST, COLLECTION, ITEM, UP, etc. — each a LinkRelation. Preferring these standard rels for pagination and navigation makes responses interoperable with generic hypermedia clients; use custom string rels for domain-specific relations. IanaLinkRelations also offers isIanaRel(...) to check whether a given relation name is a registered one.
code
java · 14 linesimport static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.IanaLinkRelations;
EntityModel<Order> model = EntityModel.of(order);
model.add(linkTo(methodOn(OrderController.class).getOrder(id)).withSelfRel());
model.add(linkTo(methodOn(OrderController.class).getItems(id)).withRel("items"));
model.add(linkTo(methodOn(OrderController.class).next(id)).withRel(IanaLinkRelations.NEXT));
// HAL:
// "_links": {
// "self": {"href": "http://host/orders/7"},
// "items": {"href": "http://host/orders/7/items"},
// "next": {"href": "http://host/orders/8"}
// }go deeper
Know self vs. named rels and that withSelfRel is the shortcut.
Explain the two withRel overloads and name several IanaLinkRelations constants.
Discuss when to prefer standard rels vs. custom, and same-rel array serialization in HAL.
Reason about interoperability: standard rels let generic clients traverse the API; custom rels raise coupling.
A hypermedia **link relation** (rel) is the label that tells a client what a link is *for*: `self` points at the current resource, `next` at the next page, `orders` at a related collection. Spring models a relation with the `org.springframework.hateoas.LinkRelation` interface (a thin wrapper around a String value). **Turning a WebMvcLinkBuilder into a Link with a rel:** - `.withSelfRel()` — shorthand for the ubiquitous `self` relation. It is exactly equivalent to `.withRel(IanaLinkRelations.SELF)` (the value string is `"self"`). - `.withRel(String rel)` — attaches a custom, domain-specific relation, e.g. `.withRel("orders")` or `.withRel("cancel")`. - `.withRel(LinkRelation rel)` — attaches a typed relation, e.g. `.withRel(IanaLinkRelations.NEXT)`. **IanaLinkRelations** (`org.springframework.hateoas.IanaLinkRelations`) holds constants for the **IANA-registered** relation types — the standardized vocabulary generic clients understand. Frequently used ones: `SELF`, `NEXT`, `PREV`/`PREVIOUS`, `FIRST`, `LAST`, `COLLECTION`, `ITEM`, `UP`, `RELATED`, `EDIT`. Each constant is a `LinkRelation`. There is also a helper `IanaLinkRelations.isIanaRel(LinkRelation)` / `isIanaRel(String)` to test whether a relation is part of the registered set. **Why prefer IANA rels:** for common navigation and pagination semantics, standard rels (`next`, `prev`, `first`, `last`, `self`) let off-the-shelf hypermedia clients traverse your API without bespoke knowledge. Reserve custom string rels for concepts that have no standard equivalent (`assign-driver`, `orders`). **HAL serialization:** the rel becomes the **key** under `_links`. So `.withRel("orders")` serializes as `"_links":{"orders":{"href":"..."}}`. If you add **multiple** links with the **same** rel, HAL renders that rel as a JSON **array** of link objects rather than a single object. **Gotchas:** - `self` is special mostly by convention/tooling, but structurally it is just another rel. - Custom rels are case-sensitive strings; be consistent. - CURIE-based/compact rels are a separate concern handled by the HAL configuration; withRel just names the relation.
- What happens in HAL output if you add two links with the same rel?HAL renders that rel as a JSON array of link objects instead of a single object, so clients must be prepared for either shape (or you configure the HAL RenderSingleLinks policy).
saying these in an interview costs you the question
- Claiming withSelfRel and withRel("self") behave differently — they yield the same 'self' relation.
- Thinking IanaLinkRelations values are arbitrary KataJob/Spring names rather than IANA-registered standard rels.
- Assuming custom rels must be registered somewhere to be valid.