Use @RepositoryRestResource instead of custom CRUD controllers
ID |
java.spring_use_repository_rest_resource |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Best Practice |
Language |
Java |
Tags |
best-practice, code-style, spring |
Description
Reports controller classes that inject a Spring Data repository and expose its CRUD operations through custom handler methods. Using @RepositoryRestResource on the repository interface eliminates boilerplate controller code and provides a standard HAL-compliant REST API automatically.
A repository is recognised by the base interface it extends — Repository, CrudRepository, PagingAndSortingRepository, ListCrudRepository, ListPagingAndSortingRepository, ReactiveCrudRepository or JpaRepository — and never by a Repository name suffix. So an interface named AuditRepository that extends nothing is not reported, while a CrudRepository subinterface named AccountStore is. Because the repository normally lives in its own file, the injected field type is resolved across the whole project; a type that cannot be resolved is not reported.
A controller whose injected repository already carries @RepositoryRestResource is not reported: the advice is already in place, and the controller is an extra endpoint on top of the generated one.
Rationale
Writing a custom @RestController that delegates every operation to a CrudRepository or JpaRepository is boilerplate that Spring Data REST can generate automatically. The hand-written wrapper is harder to maintain, may miss pagination, HATEOAS links, and ETags, and introduces a surface for bugs.
// Bad - manual CRUD wrapper
@RestController
public class UserController {
@Autowired UserRepository repo;
@GetMapping("/users")
public Iterable<User> findAll() { return repo.findAll(); }
}
Remediation
Annotate the repository with @RepositoryRestResource and remove the controller.
// Good - auto-exposed REST endpoint
@RepositoryRestResource(path = "users")
public interface UserRepository extends CrudRepository<User, Long> { }