-1

Imagine this simple controller method :

public ResponseEntity<?> findById(@Parameter(description = "id") @PathVariable String id) {

    Optional<Model> model = repository.findById(id);
    if(model.isEmpty()) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body("Model not found");
    }

    return ResponseEntity.status(HttpStatus.OK)
            .body(model.get());
}

It returns the model if it is found or an error string message if not. The case could be more complexe then this.

So I'm returning a String or a Model types, which could not be bound to the generic type of ResponseEntity.

My question is why spring team designed this class as a generic type ? or am I using wrong this object ?

flywell
  • 384
  • 3
  • 20
  • Are you asking why `ResponseEntity` is generic or why `findById()` returns `ResponseEntity>`? `findById()` is not generic and `ResponseEntity` is not used only with `findById()` (I presume). So please clarify your question. – ernest_k Apr 20 '21 at 07:26
  • `findById()` returns `Optional` I'm asking for why `ResponseEntity` is generic – flywell Apr 20 '21 at 07:30

2 Answers2

1

When you define your API you define what is the type of the object you will return in case of the operation goes OK, this is the object that you should use in the generic type of the response entity.

If you want to return different types you can remove the generic and return only a ResponseEntity and add to it whatever object you want

JArgente
  • 2,239
  • 1
  • 9
  • 11
  • why should I throw an exception ? this is a normal flow control, the case is expected, I shouldn't throw any expcetion – flywell Apr 20 '21 at 07:31
  • If the same endpoint can response two different objects and it is not an error you should think if it is not better to have two different endpoints and each one returns a different response – JArgente Apr 20 '21 at 07:33
  • Other option is, if you serialize your response always as json, return a String or a JsonNode then is the client the one that has the responsibility of understand what is the response – JArgente Apr 20 '21 at 07:34
  • I cannot check if the model id exists in another endpoint ! – flywell Apr 20 '21 at 07:34
  • 2
    Using exceptions to handle a common case is a bad idea. – M. Deinum Apr 20 '21 at 07:43
  • Yes I am totally agree and because of that I said to use exception in case of error because at first in the question was saying to show an error message – JArgente Apr 20 '21 at 07:46
  • 1
    In the question it isn't an error, but a common case. En exception is for an exceptional case, like the whole database is down. Not for not finding a record. – M. Deinum Apr 20 '21 at 07:52
  • Ok, I haven't understand well the question, Anyway you can use the ResponseEntity without the generic type, so you can return different objects in it. I will edit the answer to avoid misunderstanding about the exceptions – JArgente Apr 20 '21 at 08:38
  • Yes I can remove the generic type as I did in the question, tks – flywell Apr 20 '21 at 08:58
1

Among other reasons, ResponseEntity<T> is also returned by Spring's RestTemplate HTTP client. The generic type allows the client code to specify the type that should be used to interpret the HTTP response and get an appropriate Java object as the response body.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • So what's the best way to write controller methods ? Or I just have to discard the generic type ? – flywell Apr 20 '21 at 13:49
  • @flywell If you know the type of the response, put it in your method signature. It will provide compiler checking that you're returning what you expect, and it will help future programmers (you) understand the expected behavior of the controller. – chrylis -cautiouslyoptimistic- Apr 20 '21 at 13:53
  • Of course I know it but it won't compile, see code in my question, `String` won't match `Model` – flywell Apr 20 '21 at 13:54
  • @flywell In that case, assuming you don't want to use exceptions (stylistic choice), you will need to use `>`. Note that modern practice tends toward using a politely-formatted JSON object for error responses rather than a bare string; see, for example, the default Boot response for a 404 (`/path/not/found`). – chrylis -cautiouslyoptimistic- Apr 20 '21 at 13:56