Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC - Calling a rest service from inside another rest service

I'm currently having a really weird issue with calling one REST service from inside another one and I could really use a hand in working out what I'm doing wrong.

So first off, a bit of context:

I have a webapp which calls off to a REST service to create a user account (for the sake of this explanation, the endpoint is localhost:8080/register). Earlier in the user journey I've called a different service to create the user's login credentials localhost:8090/signup but I need to check a few things in the call to /register so inside the call I'm calling out to a different endpoint on 8090 to get this information (localhost:8090/availability). Long story short, the webapp calls localhost:8080/register which in turn calls localhost:8090/availability.

When I call the availability endpoint directly, from either a REST client or the webapp itself, everything works as expected, but for some strange reason, when I call it from inside the call to the register endpoint I get a HTTP415. Anyone have any insight into what's going wrong?

The register controller looks like this:

@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public UserModel createUser(@RequestBody UserModel userModel) throws InvalidSignupException {

    // a load of business logic that validates the user model

    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<Boolean> response = restTemplate.postForEntity("http://localhost:8090/availability",
            userModel.getUsername(), Boolean.class);
    System.out.println(response.getBody());

    // a load more business logic

    return userModel;
}

And the availability controller looks like this:

@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public Boolean isUsernameAvailable(@RequestBody String username) {
    
    // a load of business logic that returns a boolean
    return Boolean.TRUE;
}

Full disclosure - in practice, what I've shown as the contents of createUser() are actually several calls up the call stack, using the same class as I use to call the services from the webapp (which works perfectly well in that context), and I'm not actually just returning true in isUsernameAvailable (because that would be silly) but this is the simplest version of the code that replicates the issue.

My current assumption is that I'm doing something that I'm going to kick myself over when I see it but I've been staring at this code too long to be able to see it any more.

Edit Vikdor's comment below solved this problem for me. I changed the createUser method to:

@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public UserModel createUser(@RequestBody UserModel userModel) throws InvalidSignupException {

    // a load of business logic that validates the user model

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter()));
    ResponseEntity<Boolean> response = restTemplate.postForEntity("http://localhost:8090/availability",
            userModel.getUsername(), Boolean.class);
    System.out.println(response.getBody());

    // a load more business logic

    return userModel;
}
like image 590
Rob Avatar asked Dec 29 '15 02:12

Rob


1 Answers

A HTTP415 means Unsupported Media Type. What that means is that isUsernameAvailable expects input in JSON format, but that isn't what it is getting.

Try explicitly adding Content-Type: application/json header to your HTTP request by doing the following:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
restTemplate.put(uRL, entity);
like image 181
ketan vijayvargiya Avatar answered Sep 18 '22 12:09

ketan vijayvargiya