spring-hateoas

Spring HATEOAS - Quick Reference

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "spring-hateoas" with this command: npx skills add claude-dev-suite/claude-dev-suite/claude-dev-suite-claude-dev-suite-spring-hateoas

Spring HATEOAS - Quick Reference

Full Reference: See advanced.md for affordances (HAL-FORMS), embedded resources, link relations, media types, and testing patterns.

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: spring-hateoas for comprehensive documentation.

Dependencies

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-hateoas</artifactId> </dependency>

Core Concepts

Richardson Maturity Model: Level 0: Plain Old XML/JSON (single endpoint) Level 1: Resources (multiple endpoints) Level 2: HTTP Verbs (GET, POST, PUT, DELETE) Level 3: Hypermedia Controls (HATEOAS) ← This!

EntityModel Wrapper

@GetMapping("/users/{id}") public EntityModel<User> getUser(@PathVariable Long id) { User user = userService.findById(id);

return EntityModel.of(user,
    linkTo(methodOn(UserController.class).getUser(id)).withSelfRel(),
    linkTo(methodOn(UserController.class).getAllUsers()).withRel("users"),
    linkTo(methodOn(OrderController.class).getOrdersByUser(id)).withRel("orders")
);

}

Response Format (HAL)

{ "id": 1, "name": "John Doe", "_links": { "self": { "href": "http://localhost:8080/api/users/1" }, "users": { "href": "http://localhost:8080/api/users" }, "orders": { "href": "http://localhost:8080/api/users/1/orders" } } }

CollectionModel

@GetMapping("/users") public CollectionModel<EntityModel<User>> getAllUsers() { List<User> users = userService.findAll();

List&#x3C;EntityModel&#x3C;User>> userModels = users.stream()
    .map(user -> EntityModel.of(user,
        linkTo(methodOn(UserController.class).getUser(user.getId())).withSelfRel()
    ))
    .toList();

return CollectionModel.of(userModels,
    linkTo(methodOn(UserController.class).getAllUsers()).withSelfRel()
);

}

RepresentationModelAssembler

@Component public class UserModelAssembler implements RepresentationModelAssembler<User, EntityModel<User>> {

@Override
public EntityModel&#x3C;User> toModel(User user) {
    return EntityModel.of(user,
        linkTo(methodOn(UserController.class).getUser(user.getId())).withSelfRel(),
        linkTo(methodOn(UserController.class).getAllUsers()).withRel("users")
    );
}

}

// Usage @RestController @RequestMapping("/api/users") @RequiredArgsConstructor public class UserController { private final UserService userService; private final UserModelAssembler assembler;

@GetMapping("/{id}")
public EntityModel&#x3C;User> getUser(@PathVariable Long id) {
    return assembler.toModel(userService.findById(id));
}

@GetMapping
public CollectionModel&#x3C;EntityModel&#x3C;User>> getAllUsers() {
    return assembler.toCollectionModel(userService.findAll());
}

}

Pagination Support

@GetMapping("/users") public PagedModel<EntityModel<User>> getAllUsers( @PageableDefault(size = 20) Pageable pageable, PagedResourcesAssembler<User> pagedAssembler) {

Page&#x3C;User> users = userService.findAll(pageable);
return pagedAssembler.toModel(users, userModelAssembler);

}

Best Practices

Do Don't

Use ModelAssembler pattern Build links inline everywhere

Include self links always Omit navigation links

Use standard IANA relations Invent new relation names

Add conditional links for actions Show all links regardless of state

When NOT to Use This Skill

  • Simple REST APIs - If clients don't need hypermedia navigation

  • GraphQL APIs - Use spring-graphql instead

  • Internal microservices - Often unnecessary overhead

Anti-Patterns

Anti-Pattern Problem Solution

Building links inline Duplicated code everywhere Use RepresentationModelAssembler

Missing self links Clients can't identify resources Always add withSelfRel()

Hardcoded URLs Breaks on deployment Use linkTo/methodOn builders

Inventing relations Non-standard, hard to understand Use IANA link relations

Quick Troubleshooting

Problem Diagnostic Fix

Links not serialized Check Accept header Ensure HAL media type

NullPointerException in linkTo Check controller method Verify method signature matches

Wrong base URL Check proxy config Configure server.forward-headers-strategy

Pagination links missing Check assembler Use PagedResourcesAssembler

Production Checklist

  • ModelAssemblers for all resources

  • Self links on every resource

  • Collection links from items

  • Pagination with navigation links

  • Conditional action links

  • IANA link relations where possible

Reference Documentation

  • Spring HATEOAS Reference

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

cron-scheduling

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

token-optimization

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

react-19

No summary provided by upstream source.

Repository SourceNeeds Review