Tovarisch
Tovarisch

Reputation: 59

Best use of Optionals in RestAPI Spring application

I am kind of confused about the way I should design repository -> service -> controller communication using Optionals in my RestAPI Spring app. For instance, client wants to find film by id, but film is not present and repository returns empty Optional. I have two ways of dealing with it:

  1. Service method returns Optional value or throws Exception which can be handled in Controller using ControllerAdvice.

  2. Service returns Optional and Controller deals with it (return value if present or handle exception, or maybe just do something else).

I know that using exceptions for such simple situations is not best practice, probably you may suggest other ways of letting client know that id is wrong.

Method in RestController currently:

@GetMapping("/{id}")
public FilmGetDto getFilm(@PathVariable int id) {
    return filmService.getFilm(id);
}

Upvotes: 3

Views: 7306

Answers (3)

Danish
Danish

Reputation: 150

Most followed practice I have followed or seen people doing is you should handle it in service and use wrapper class for response. By this way you will achieve two things i.e. you will have a constant Response object that you can use in all of your application and also you can use exceptions etc very easily with that. You should always handle any sought of business logic in service layer as MVC states. I am posting an example here so that you can understand better what I am trying to say here.

Controller:

@GetMapping("/{id}")
public Response getFilm(@PathVariable int id) {
    return filmService.getFilm(id);
}

Service:

public Response getFilm(int id){
  Optional<Film> film = repo.findById(id);
  return film.map(f -> Response.builder().status(200).data(f).message("request  successful"))
             .orElseGet(() -> Response.builder().status(422).data(null).message("Film with given id not found");

}

and Response class with be like as suggested by @Adrash as well

class Response {
  private int status;
  private Object data;
  private String message;
   
  //you can use lombok or IDE  generate getter setters to generate getters setters
 }

Note: I have used lombok builder method to create response object in service layer.

Upvotes: 2

user17275084
user17275084

Reputation:

You have to follow the standards, so you should not write the code in controller, instead you should write the code in services and also, you can wrap your response in a class provide it a appropriate custom message so that it makes sense to the client. as @Adarsh mentioned above the Wrapper class you can create exactly same and it would solve your problem. and follow the standards as mentioned by @Danish.

Upvotes: 1

Adarsh Gupta
Adarsh Gupta

Reputation: 121

If you want to send a message to the client about the non-existence of such id, you have to handle such edge cases. probably you can use Optional and handle if optional.isPresent() returns false, you can send a customized message and let your client know that no data exist with such id.

You can use a wrapper class to achieve this.

class ErrorResponse {
  private String status;
  private int statusCode;
  private String message;

  public ErrorResponse(String status, int statusCode, String message){
      this.status = status;
      -----
      -----
   }
}

Set this feilds and return this class object as a response.

Upvotes: 1

Related Questions