简体   繁体   中英

Alternative response spring boot api rest

I´m beginner in REST API and Spring Boot. I have a doubt about how to handle the different responses a request can have. For example if I post data of a credit card

{
    "number": "3434 3434 3434 3434",
    "date_expiration": "09-19",
    "identification_card": 23232323
}

then in @RestController

@PostMapping("/card")
public ResponseEntity<CreditCard> payCard(@Valid @RequestBody CreditCard creditCard){
      CreditCard creC = cardService.registerCard(creditCard);
      return new ResponseEntity<>(creC, HttpStatus.OK);    
}

In this case I return an object of ResponseEntity. What happens if the date_expiration is expired or the identification_card doesn't correspond to the client? They are logical validations that are resolved in the service and can trigger different responses. How should I handle them?

Here you are using same object as your Request body and Response body. That is not a standard practice.

You should have separate objects for Request/Response. In request object you should have only the information you need from the user. But in the response object you should have information you want to send in response and also validation information like Error Details which includes error code and error description which you can use to display validation error to the user.

Hope this helps.

Well, if date_expiration is expired or identification_card doesn't behave to the customer, this is a business failure.

I like to represent Business Errors with an HTTP 422 - Unprocessable Entity . See here

You can change the return object from ResponseEntity<CreditCard> to ResponseEntity<Object> if you want to return diferent objects in your controller, although I prefer to use a ExceptionHandler in a ControllerAdvice annotated method if the purpose is to return errors.

As I said, this situation is a business failure (the credit card is expired or doesn't behave to the current user).

Here's an example. Would be something like this:

CardService.java

@Service
public class CardService {

    // ..

    public CreditCard registerCard(CreditCard card) throws BusinessException {
        if(cardDoesntBehaveToUser(card, currentUser()))) // you have to get the current user
            throw new BusinessException("This card doesn't behave to the current user");

        if(isExpired(card)) // you have to do this logic. this is just an example
            throw new BusinessException("The card is expired");

        return cardRepository.save(card);
    }

}

CardController.java

@PostMapping("/card")
public ResponseEntity<Object> payCard(@Valid@RequestBody CreditCard creditCard) throws BusinessException {
    CreditCard creC = cardService.registerCard(creditCard);
    return ResponseEntity.ok(creC);
}

BusinessException.java

public class BusinessException extends Exception {

    private BusinessError error;

    public BusinessError(String reason) {
        this.error = new BusinessError(reason, new Date());
    }

    // getters and setters..
}

BusinessError.java

public class BusinessError {

    private Date timestamp
    private String reason;

    public BusinessError(String Reason, Date timestamp) {
        this.timestamp = timestamp;
        this.reason = reason;
    }

    // getters and setters..
}

MyExceptionHandler.java

@ControllerAdvice
public class MyExceptionHandler extends ResponseEntityExceptionHandler {

    // .. other handlers..

    @ExceptionHandler({ BusinessException.class })
    public ResponseEntity<Object> handleBusinessException(BusinessException ex) {
        return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body(ex.getError());
    }

}

If the credit card is expired, the JSON will be rendered as:

{
  "timestamp": "2019-10-29T00:00:00+00:00",
  "reason": "The card is expired"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM