0

Why my required=false at Pathvariable on my controller is not working and always throw me exception that I don't set an parameters into my endpoint?

    @GetMapping(path="/{userId}")
    public Map<String, String> getCompleteAlgTemp(
            @PathVariable(required = false, value = "userId") Long userId,
            @ApiIgnore @CookieValue(CookieName.AUTHENTICATION) String token
    ) throws ErrorException {
Savior
  • 3,225
  • 4
  • 24
  • 48
  • What exception? What URL are you sending the request to? Let's see the complete mapping as well. – Savior May 20 '20 at 19:41
  • 1
    Does this answer your question? [Can @PathVariable return null if it's not found?](https://stackoverflow.com/questions/5493767/can-pathvariable-return-null-if-its-not-found) – Savior May 20 '20 at 19:54
  • @Savior i see in swagger that i can't launch my request because my ```userId``` is required –  May 20 '20 at 20:00

2 Answers2

1

Because it is a @PathVariable and is therefore used in the URL.

You can't have optional stuff in your URL, because this makes URLs ambiguous and the framework can't resolve the correct method that should be called. In the worst case, it may lead to the wrong method being called, which you don't want to happen.

On a more theoretical point, this also would contradict the REST principles, in that the URL should denote the resource that is to be manipulated, not the input data for the particular request. The resource location should be unique, unambiguous and "stable", i.e. should not vary from one request to the other.

That's why you cannot have optional parameters as PathVariables. You can have them in pretty much every other location - as query parameter, as a cookie, in the headers, or in the body, but not in the URL.

Mike
  • 143
  • 5
1

You have to specify both / and /{userId} paths in GetMapping#path

@GetMapping(path= {"/", "/{userId}"})
public Map<String, String> getCompleteAlgTemp(
        @PathVariable(required = false, value = "userId") Long userId,
        @ApiIgnore @CookieValue(CookieName.AUTHENTICATION) String token
) throws ErrorException {
Vitalii Vitrenko
  • 9,763
  • 4
  • 43
  • 62
  • It's not solution because, now i have two endpoints in swagger, one on ```"/"``` and second on ```/{userId}``` –  May 20 '20 at 20:08
  • @Piotrek This is what `PathVariable#required` is all about. You did not mention anything about swagger in your question. If you need one endpoint then you have to use [RequestParam](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html). – Vitalii Vitrenko May 20 '20 at 20:12
  • so, for what, in ```Pathvariable``` we can use ```required``` parameter? –  May 20 '20 at 20:31
  • To map two endpoints (with and without a variable) to one controller method. – Vitalii Vitrenko May 20 '20 at 22:41
  • @Piotrek, you obviously need some kind of special handling for the case where `userId` is not specified (null). Just declare a second method with a `"/"` path that contains the logic for that special case, and leave the `"/{userId}"`method with `required = true` (which is the default). Again, there is no way around having two endpoints because a `/{userId}` endpoint without a `userId` ***is*** de facto a `/` endpoint. – Mike May 21 '20 at 00:56