Spring HATEOAS
Give the client a map along with the data — so it knows what to do next.
The Ramoji Film City Map Analogy:
When you buy a ticket at Ramoji Film City, you don’t just get a ticket. You get a map that says: “To go to Action Cinema, turn left. To go to the restaurant, turn right.”
A standard REST API just gives you a ticket (data). A HATEOAS API gives you the ticket AND the map (links). The client doesn’t need to guess that the delete URL is /api/books/1. The API literally provides the delete URL in the response!
- EntityModel<T>: A wrapper that holds your data (the Entity) and a list of WebLinks.
- WebMvcLinkBuilder: A tool to build links pointing to your controller methods safely.
- Self Link: A link pointing to the exact resource itself.
Add the HATEOAS dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>The Controller (BookController.java)
package com.devinhyderabad;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@RestController
@RequestMapping("/api/books")
public class BookController {
@GetMapping("/{id}")
public EntityModel<Book> getBook(@PathVariable Long id) {
// 1. The actual data
Book book = new Book(id, "HATEOAS Guide", "Deva");
// 2. Wrap it in an EntityModel and add links
return EntityModel.of(book,
linkTo(methodOn(BookController.class).getBook(id)).withSelfRel(),
linkTo(methodOn(BookController.class).getAllBooks()).withRel("all-books")
);
}
@GetMapping
public List<Book> getAllBooks() {
return List.of(new Book(1L, "Book 1", "Author 1"));
}
}
class Book {
private Long id;
private String title;
private String author;
public Book(Long id, String title, String author) {
this.id = id; this.title = title; this.author = author;
}
public Long getId() { return id; }
public String getTitle() { return title; }
public String getAuthor() { return author; }
}If you call /api/books/1, the JSON response includes a _links section:
{
"id": 1,
"title": "HATEOAS Guide",
"author": "Deva",
"_links": {
"self": {
"href": "http://localhost:8080/api/books/1"
},
"all-books": {
"href": "http://localhost:8080/api/books"
}
}
}The code demonstrates the core HATEOAS pattern:
- EntityModel.of(book, links): Wraps the book data and attaches hypermedia links to it. The response JSON now includes both the data and a
_linkssection. - WebMvcLinkBuilder.linkTo(methodOn(...)): A type-safe way to generate URLs. It inspects the controller method and generates the correct URL. If you change the method name or route, the links update automatically.
- withSelfRel(): Creates a link with rel=“self” pointing to this exact resource. withRel(“all-books”): Creates a link pointing to another resource (like a parent list).
The client can now follow these links instead of hardcoding URLs, making the API more discoverable.
Interview Question: “What is the Richardson Maturity Model?”
Answer: It defines 4 levels of REST APIs:
- Level 0: Using HTTP as a transport (e.g., SOAP).
- Level 1: Using proper URLs for resources (
/books/1). - Level 2: Using correct HTTP verbs (GET, POST, PUT, DELETE) and status codes.
- Level 3: HATEOAS. Providing hypermedia links in the response to drive the application state.
Enterprise Note: While HATEOAS is the “purest” form of REST, many modern enterprise Single Page Applications (SPAs) skip it because it increases response payload size and the frontend often hardcodes the URLs anyway. It is most useful for public APIs consumed by unknown third-party clients.
Key Takeaways
- ✅ HATEOAS is Level 3 REST — responses include links to guide the client
- ✅ EntityModel wraps data with hypermedia links
- ✅ WebMvcLinkBuilder generates type-safe links to controller methods
- ✅ Self links point to the resource itself; rel links point to related resources
- ✅ HATEOAS is most useful for public APIs consumed by third-party clients
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login