2

I am trying to send POST-request to my local app using cURL:

host="http://localhost:8080"
$(curl -s -X POST -H "Content-Type: application/json" -d '{"name":"Test", "description":"Test"}' $host/games/new?user_id=c13fb734-c72a-48a0-9fd7-5fbc79c6285a)

My controller:

@RequestMapping("games")
@RestController
public class GameController {

    private static final String ROOT_URL = ServerConfig.GAMES_HOST + "/games";

    @PostMapping(value = "new")
    public ResponseEntity<String> add(@RequestParam("user_id") UUID userId,
                      @RequestBody String newGame) {
        String url = ROOT_URL + "/new?userId=" + String.valueOf(userId);
        RestTemplate template = new RestTemplate();
        return template.postForEntity(url, newGame, String.class);
    }
}

But in Spring I'm getting an error:

{"errors":["user_id should be of type java.util.UUID"],"status":"BAD_REQUEST","message":"Failed to convert value of type 'java.lang.String' to required type 'java.util.UUID'; nested exception is java.lang.IllegalArgumentException: Invalid UUID string: new"}

I.e. cURL sends new as value of user_id. Where can error be?

Kim Kern
  • 54,283
  • 17
  • 197
  • 195
Denis Sologub
  • 7,277
  • 11
  • 56
  • 123
  • 1
    What if you include the user_id in the JSON? like `-d '{"name":"Test", "description":"Test", "user_id":"c13fb734-c72a-48a0-9fd7-5fbc79c6285a"}'` – Thomas Leu Jan 20 '18 at 11:56

1 Answers1

1

Analysis

Long story short, conceptually, @RequestParam and @RequestBody are mutually exclusive: query parameters (@RequestParam) are sent as a request body.

Please see the additional details here:

Solution

Currently, there are two alternatives:

  1. Stick to the request parameters (@RequestParam) only: pass every parameter (i.e. every JSON property) as a query parameter.
  2. Stick to the request body (@RequestBody) only, for example:

    1. Pass everything as a JSON request body.
    2. Pass everything as a JSON request body, except the user_id parameter. The parameter may be made @PathVariable and the @RequestMapping should use the appropriate placeholder to reference it.