Conditional ResponseEntity — Different Status Codes Based on Logic
Fast recall
Quick revision
Core answer
Practical conditional response handling in REST controllers
Using ResponseEntity wildcard everywhere or returning null—lose type safety and create confusion
Show the Optional chaining pattern as the standard Spring Boot approach for conditional responses
Interview-ready guide
Interview answer
For example, service.find(id).map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build()) clearly maps presence to 200 and absence to 404. A create command that can conflict is often clearer when the service throws DuplicateOrderException and shared advice maps it to 409 ProblemDetail.
Conditional ResponseEntity — Different Status Codes Based on Logic
Direct Answer
A controller can return different ResponseEntity values from clear branches, map an Optional for a simple present/missing case, or throw a domain exception handled by advice. Choose the form that keeps business rules in the service and HTTP translation at the web boundary. ResponseEntity<?> does not make runtime clients lose compile-time Java type information; its main drawback is a less precise controller signature/documentation.
Code Example
@RestController
@RequestMapping("/api/customers")
public class CustomerController {
@Autowired
private CustomerService customerService;
@GetMapping("/{id}")
public ResponseEntity<Customer> getCustomer(@PathVariable Long id) {
return customerService.findById(id)
.map(ResponseEntity::ok) // 200 if found
.orElse(ResponseEntity.notFound().build()); // 404 if missing
}
@GetMapping("/{id}/status")
public ResponseEntity<?> getCustomerStatus(@PathVariable Long id) {
var customer = customerService.findById(id);
if (customer.isEmpty()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse("Customer not found")); // Different body type
}
return ResponseEntity.ok(new StatusResponse(customer.get().status()));
}
@PostMapping("/{id}/activate")
public ResponseEntity<Customer> activateCustomer(@PathVariable Long id) {
return customerService.activate(id)
.map(ResponseEntity::ok)
.orElseGet(() -> ResponseEntity.status(HttpStatus.CONFLICT)
.body(null)); // 409 if already active
}
}
Common Mistakes & Pitfalls
- Using ResponseEntity wildcard everywhere: Writing all methods as ResponseEntity<?> loses type safety. Clients and tests can't rely on the compile-time type. Use it only when you truly return different types.
- Returning null: Some freshers return null from a controller method when data isn't found. Spring translates this to 200 OK with an empty body, which is semantically wrong. Always return ResponseEntity.notFound() explicitly.
- Ignoring Optional: Writing customerService.findById(id); if (customer == null) return notFound(); else return ok(customer); is verbose and misses Java's functional API. The Optional.map pattern is one line and cleaner.
- Nested if-else: Building complex nested if-else trees inside a controller method makes code hard to read. Extract the logic to a service method and return a Result or Either type that the controller maps to ResponseEntity.
Check your understanding
Answer these without looking back at the article.
- What is the idiomatic Optional + ResponseEntity pattern in Spring?
- When should you throw exceptions vs return ResponseEntity directly?
- What is @ControllerAdvice and how does it handle ResponseEntity?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.