2

This is my first question here, I am a beginner in using the REST template and Spring and I apologize if I am asking simple questions.

I am trying to call a delete method from another component using the REST template. The response I receive in POSTMAN is the following JSON:

    {
       "code": 100,
       "message": "my message"
    }

I should not be able to delete the object, so my request fails with org.springframework.web.client.HttpClientErrorException.

In the logs all I see is the:

[Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException: 400 Bad Request] with root cause...

I have searched a bit and I have seen that when try to call a rest service with restTemplate, the body of response is lost if it returns a 400.

This is the code I have used to catch the HttpClientErrorException:

try{
            restTemplate.delete(url);
            }
            catch (HttpClientErrorException e) {
                LOG.error("FM HttpClientErrorException caught");
                LOG.error("FM response body : {}", e.getResponseBodyAsString());
                LOG.error("FM response headers message: {}", e.getResponseHeaders().toString());
                LOG.error("FM response message : {}", e.getMessage());
                LOG.error("FM response status : {}", e.getStatusCode());
            }

I have seen in other posts DELETE in Spring RestTemplate with HttpEntity<List> that one solution is to catch the exception and try to get the body of the response.

However, in my case this is always empty.

I have tried getting the response as well using the exchange from restTemplate and then catching the Exception as above, but my body is still empty:

ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, null, String.class);
            LOG.info("FM response body : {}", response.getBody());
            LOG.info("FM response status : {}", response.getStatusCode());

Unit test result:

Unit tes2018-06-12T15:23:02,960Z  [main] ERROR c.v.b.s.impl.ServiceImpl     - HttpClientErrorException caught
2018-06-12T15:23:02,960Z  [main] ERROR c.v.b.s.impl.ServiceImpl     - response body : []
2018-06-12T15:23:02,960Z  [main] ERROR c.v.b.s.impl.ServiceImpl     - response headers message: {}
2018-06-12T15:23:02,960Z  [main] ERROR c.v.b.s.impl.ServiceImpl     - response message : 400 Bad Request
2018-06-12T15:23:02,960Z  [main] ERROR c.v.b.s.impl.ServiceImpl     - response status : 400t results:

The questions are:

  1. Can we retrieve the JSON from the response using a REST delete call?
  2. Can we do the same using the exchange? If yes, how can we retrieve the JSON sent? I tried both and the body is always empty.

I have seen also this post: What is the HTTP status return code for a successful DELETE statement in REST? The 3rd question would be then:

  1. Is it a good practice to return a JSON and say why the delete cannot succeed?

Thank you very much, any help or suggestion regarding the code or the solution is appreciated.

  • 1
    Actually the semantics of `DELETE` accroding to [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.3.5) say nothing about the resource being deleted but only the association (link) pointing to it. If the state of the resource is also deleted is an implementation detail. If you are not supposed to invoke a `DELETE` operation on a resource you probably should return a `405 Method Not Allowed` error code instead to indicate the client that this operation is not supported by the resource endpoint. An exception should contain details why it failed but not the current state of the resource – Roman Vottner Jun 13 '18 at 12:59
  • 1
    If you want to send customized error messages to the client you might have a look at [custom error messages or ExceptionHandlers](http://www.baeldung.com/global-error-handler-in-a-spring-rest-api) – Roman Vottner Jun 13 '18 at 13:04

1 Answers1

0

1,2) Yes, it is possible. Based on my own experience, I much prefer to use the REST Client that comes with the JAX-RS specification, than the one that comes with Spring. https://docs.oracle.com/javaee/7/api/javax/ws/rs/client/package-summary.html

You can make any request you like and then just get the body, independent of the result code. Nothing gets lost.

I know this doesn't fully answer your first question, but might be helpful.

3) The best practice is to return different error codes signifying the different reasons. Was it access denied? Was the resource not available? Was there an unexpected error?

You can then document all this fairly easy using Swagger/OpenApi/etc.

These should all be enough to handle the potential exceptions. If this is still not enough, you might want to create support methods that validate that a resource can be deleted (ex: GET /api/users/{id}/isDeletable).

Guilherme Mussi
  • 956
  • 7
  • 14
  • Answering a question targetet to Spring-Data-Rest with a recommendation to use JAX-RS feels a bit odd IMO. Further, if you need to document endpoints via Swagger/OpenApi/... you have, with high certainty, the next RPC-like Web API which you just call REST. Finally, you don't need such "helpers". HTTP already provides `OPTIONS` that exactly tell you whether invoking `DELETE` is an allowed operation or not. If you don't retrieve it beforehand or send an unsolicited `DELETE` request anyway, the server will tell you with a `405 Method Not Allowed` failure that you can't use delete ... – Roman Vottner Jun 13 '18 at 13:12