skip to content

What is the difference between withSelfRel() and withRel(...), and how do IanaLinkRelations fit in?

level: middleimportance: should knowfreq 45%

answer

  1. withSelfRel() == withRel(IanaLinkRelations.SELF)
  2. withRel(String) custom, withRel(LinkRelation) typed
  3. IanaLinkRelations = registered vocabulary (NEXT/PREV/FIRST/LAST)
  4. rel becomes _links key in HAL
  5. same rel twice → JSON array

basics

~10 s

withSelfRel() 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 s

Every 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 lines
java
import 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

for a junior

Know self vs. named rels and that withSelfRel is the shortcut.

for a middle

Explain the two withRel overloads and name several IanaLinkRelations constants.

for a senior

Discuss when to prefer standard rels vs. custom, and same-rel array serialization in HAL.

for a principal

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.

context