ISP in Spring Boot — Repository interfaces and service interfaces
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
In a Spring Boot application, ISP means that each class should depend on a focused contract rather than a large service or repository API. A reporting controller that only reads customers can depend on CustomerQueries; an administration use case that changes customers can depend on CustomerCommands as well.
The same idea applies to persistence. Spring Data provides interfaces with different capabilities, but their exact hierarchy varies across versions and store modules. I choose the smallest supported repository contract that fits, or place an application-owned interface in front of the Spring Data repository so business code sees only operations such as findActiveCustomer and save.
This reduces accidental dependencies and makes tests smaller because each consumer fakes only the methods it uses. It is not an authorization mechanism: a read-only type helps communicate intent, while Spring Security or service-level checks still decide who may perform an operation.
ISP in Spring Boot — Repository interfaces and service interfaces
Direct Answer
In Spring applications, apply ISP by giving each consumer the smallest useful contract. A read-only controller can depend on a query interface, while an administration use case can depend on a command interface. With Spring Data, choose or define repository interfaces deliberately; do not expose every persistence operation to code that only needs one query.
Code Example
interface CustomerQueries {
Optional<CustomerView> findById(long id);
List<CustomerView> findActive();
}
interface CustomerCommands {
CustomerView create(CreateCustomer command);
void deactivate(long id);
}
@RestController
final class CustomerReportController {
private final CustomerQueries queries;
CustomerReportController(CustomerQueries queries) {
this.queries = queries;
}
@GetMapping("/customers/active")
List<CustomerView> active() {
return queries.findActive();
}
}
The controller's Java contract contains no write operation. Authorization is still required because type shape alone cannot protect an HTTP endpoint.
Common Mistakes & Pitfalls
- Extending the largest repository by habit: choose capabilities deliberately or hide persistence behind an application-owned port.
- Assuming one Spring Data hierarchy for every version and store: verify the current module's official API.
- Treating a read-only Java type as authorization: enforce access at the web or service boundary.
- Injecting a narrow interface and later downcasting to the implementation: that restores the dependency ISP was meant to remove.
Check your understanding
Answer these without looking back at the article.
- What is the difference between CrudRepository and JpaRepository?
- How do you define a read-only repository in Spring?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.