Description
The way the DomainClassConverter acts is unclear to me. The documentation states that it can be used to have @PathParameter
directly being looked up instead of manually doing it.
So the following code inside of a controller works perfectly:
@GetMapping(path = "/{entityId}")
public void get(@PathVariable("entityId") Entity myEntity)
However, when I provide an entityId
that does not exist, spring responds with 500 stating that the entityId
parameter has not been provided. Which is not true, it has been provided the DCC could not find an entity to that value. So the correct response should be a 404.
I came across this issue #26296 where two solutions were provided and additionally added to the documentation:
- Configure the
PathVariable
settingrequired=false
- In my case, I want this to be required, so that wouldn't be an option. The only way would be to check for null and trigger a 404 response manually however that would also cause a 404 response if the
entityId
is not present in the request.
- In my case, I want this to be required, so that wouldn't be an option. The only way would be to check for null and trigger a 404 response manually however that would also cause a 404 response if the
- Handle the
MissingPathVariableException
to return a 404- In my opinion this is wrong because the absence of a required path variable should not result in a 404 but rather a 400 response since the request was malformed.
As of what I've found out, there is no way to trigger a 404 without using any of the two above solutions. The expected behavior that I imagine (for the above code) would look like this:
Request | Expected Response | Controller Invocation |
---|---|---|
GET / |
400 Bad Request |
❌ |
GET /not-existing |
404 Not Found |
❌ |
GET /existing |
200 OK |
get(Entity) |
Additionally for optional path variables (i.e. @PathVariable(required = false)
):
Request | Expected Response | Controller Invocation |
---|---|---|
GET / |
200 OK |
get(null) |
GET /not-existing |
404 Not Found |
❌ |
GET /existing |
200 OK |
get(Entity) |
Since changing the behavior would probably be considered a breaking change one less breaking solution could be to allow the DCC to throw certain exceptions that would then not get interpreted as conversion failures and simply passed through (so users can override the DCC to throw EntityNotFoundException
instead of it returning null
)