Issue
I am using Spring Boot 2.2.4.RELEASE
& i have a REST api, exposing several endpoints. If the DB is down, i would like to return a 503 to the caller.
I could use the DataSourceHealthIndicator
provided for free by Spring Boot
if the DataSource
is configured etc like so:
import org.springframework.boot.actuate.health.Status;
@Autowired
private DataSourceHealthIndicator d;
@PostMapping(value = "/{id}")
public ResponseEntity<jsonResponse> someMethod()(
@PathVariable String id,
@Valid @RequestBody SomeDto someDto) {
//some code
if(Status.DOWN.getCode().equals(d.getHealth(false).getStatus().getCode())) {
return new ResponseEntity<>(jsonResponse, HttpStatus.SERVICE_UNAVAILABLE);
}
Is there a better way to do it as i believe it is hitting the DB everytime the end-point is being called and therefore probably an expensive way of doing.
Solution
If you want to rely on a Spring Boot solution then I would suggest Spring Cache https://spring.io/guides/gs/caching/
Add the Maven dependency <artifactId>spring-boot-starter-cache</artifactId>
, enable caching in the SpringBoot Application class with @EnableCaching
, then define which methods should cache the result.
This method will hit the DB only during the first call, all others invocation relies on the cached value.
@Cacheable("records")
public Record getByName(String name) {
return getRecordRepository().findByName(name);
}
If using the Spring native (in-memory) cache you need to evict the objects at some point to ensure you don't hold stale data (unless it is a readOnly object that never changes, not a very common use case probably).
In your scenario (if I understand correctly) you could have a thread then every x seconds check the DB, and if healthy you can evict the cache with a dedicated method:
@CacheEvict(allEntries = true, cacheNames = { "records"})
public void evictAllRecords() {
// evict all records every 10 minutes
}
Answered By - Beppe C
Answer Checked By - Gilberto Lyons (JavaFixing Admin)