bkumon
bkumon

Reputation: 31

What is the best way to return different types of ResponseEntity in Spring-Boot

I would like to return two different response for a spring boot rest API.

I should not be using <?> wild card as i get the sonar issue "Generic wildcard types should not be used in return types"

My code:

@GetMapping(path = {"/v1/{type}"}, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> method(@PathVariable(value = "type")  boolean type) {
        boolean b = type;// some logic
        if (b) {
       
            Success result=new Success();
            result.setSuccess("Yes");
        
            return new ResponseEntity<>(result,HttpStatus.OK);
        }
        else {
            Error result=new Error();
            result.setError("No");
            return new ResponseEntity<>(result,HttpStatus.CONFLICT); //appropriate error code
        }
    }

Any idea how to handle this situation.

Update:

    public interface MyResponse{
      public Success getSuccessObj();
      public Error getErrorObj();
    }
    @Service
    public class Success implements MyResponse {
     public Error getErrorObj(){
      return null;
    }
    public Success getSuccessObj(){
     Success s=new Success();
      return s;
    }
    @Service
    public class Error implements MyResponse {
     public Error getErrorObj(){
      Error e=new Error();
       return e;
     }
     public Success getSuccessObj(){
      return null;
     }

Upvotes: 0

Views: 3291

Answers (2)

Howie S. Nguyen
Howie S. Nguyen

Reputation: 50

This should work

I tried the snippet below by myself and it worked for me:

@GetMapping("/testresponse/{id}")
public ResponseEntity<?> testMyResponse(@PathVariable("id") int id)
{
    if(id==1)
        return ResponseEntity.ok(new Success());
    else return new ResponseEntity<>(new Error(), HttpStatus.CONFLICT);
}

public class Success {
    private String msg = "Success";
    
    public String getMsg() {
        return msg;
    }
}

public class Error {
    private String msg = "Error";
    
    public String getMsg() {
        return msg;
    }
}

EDIT: The solution as below doesn't work

You should also define an interface for both Success and Error classes. Let say the interface MyResponse

And then change your method declaration, it would look like this

public ResponseEntity<MyResponse> method(@PathVariable(value = "type")  boolean type) 

If so, the return statement, could be:

return new ResponseEntity<>(result, HttpStatus.OK);

Or

//for status 200 OK
return ResponseEntity.ok(result);

Upvotes: 0

xerx593
xerx593

Reputation: 13261

Not claiming to be "the best way", but one approach can be:

  1. Introduce:

    package com.my.package;
    
    public interface MyResponseI { //if Error, Success (and others) have more "in common", you can also introduce an (abstract) class (with fields, methods, etc.)!
    }
    
  2. "Implement"/Extend:

    public class Success implements com.my.package.MyResponseI { //everything else can stay}
    

    as

    public class Error implements com.my.package.MyResponseI { //everything else can stay}
    
  3. Use as Response Type:

    @...
    public ResponseEntity<com.my.package.MyResponseI> ...
    
  4. (on client side distinguish).

..and in "your domain" (error, success, ...), you are free to use any "tweaks" of a object oriented design.


Useful links/entries:

Upvotes: 1

Related Questions