When an API is asked for a resource that can’t be found, it is expected to return the HTTP 404 response code. To meet this requirement we don’t need to clutter our application logic with throwing exceptions and dealing with them along the way.
The concept described in this post can be especially helpful when we are working on a proof of concept or want to spike through a problem.
The most common way of handling a request for a non-existent resource is to throw a custom exception and propagate it to a controller layer. A developer can create an @ControllerAdvice class and deal with situations that are common among various controllers – like the
404 error. It’s a great way for advanced error management — e.g when we want to back a user with a friendly message alongside accurate details of what caused the failure.
|However, handling exceptions globally requires a deep understanding of business requirements and a well planned architecture. And it may not even be needed at all (YAGNI).|
Instead, you can start with a handy but still suitable idea described below.
Optional in Spring Boot Repository interface
CrudRepository provides a method for getting a specified entity which returns an
Optional always carries the information whether a requested resource could be found — it’s either empty or has a reference to the sought object.
Create a service
Wrap calls to the repository in a service. The following
CookieService has a dependency on
CookieRepository and implements one method —
Now we can inject the
CookieService into the
CookieController and call the
findOneById method in the following endpoint:
Calling map() and orElse() functions allows us to use the mapping function if a value is present — when the cookie is found it will be returned in the response body with
status 200. In case of an empty
Optional, the mapping function is omitted and the endpoint returns an empty response body with the
We can easily test if the response status is correct:
Thanks to the
Optional characteristic we can handle requests for a non-existent resource in a simple and straightforward way. It’s very convenient when we want to create a minimum viable product and we can always add more sophisticated error handling in a future iteration.