- changed status to open
Wrong api operation returned by ApiOperationResolver#findApiOperation in /{id} vs /
I have 2 api operations:
/{id} - get a single foo
/ - get all the foos
The problem is that when the http request is / (get all the foos), I get an error saying 'id' is required but is missing.
It appears that ApiOperationResolver#findApiOperation returns the wrong api operation.
In the findApiOperation method, the matchingPaths list contains both ApiPath objects. The ApiOperationResolver::specificityScore method causes the "/{id} - get a single foo" to be returned (as its more specific).
=====possible solutions=====
Looking at ApiPathImpl#partMatches, the replacement regex "\\E(.*?)\\Q" is questionable, maybe it should be "\\E(.+)\\Q" ?
Alternatively, it would be good to be able to pass in a user defined function overriding ApiOperationResolver::specificityScore.
Or maybe a pass in a user defined predicate(ApiPath, NormalisedPath) -> Boolean that could be used as an additional filter.
=====error message=======
[com.atlassian.oai.validator.springmvc.InvalidRequestException: {
"messages" : [ {
"key" : "validation.request.parameter.missing",
"level" : "ERROR",
"message" : "Parameter 'id' is required but is missing.",
"context" : {
"requestPath" : "/v1/foos",
"parameter" : {
"name" : "id",
"in" : "path",
"description" : "identifier of the foo",
"required" : true,
"style" : "SIMPLE",
"explode" : false,
"schema" : {
"type" : "string",
"example" : "abc123"
}
},
"location" : "REQUEST",
"requestMethod" : "GET"
}
} ]
}]
====yaml sample=====
paths:
'/{id}':
get:
description: get a single foo
parameters:
- $ref: '#/components/parameters/fooId'
responses:
'200':
description: A single foo
content:
application/json:
schema:
$ref: '#/components/schemas/singleFoo'
/:
get:
description: get all the foos
responses:
'200':
description: All foos
content:
application/json:
schema:
$ref: '#/components/schemas/allFoos'
components:
parameters:
fooId:
name: id
in: path
description: identifier of the foo
required: true
schema:
type: string
example: abc123
Comments (4)
-
-
I reproduced the problem. It is caused by the two paths being scored the same, but then the first-defined path is being returned as the tie-breaker (e.g. if you swap the order of your paths in your spec it will work as expected).
I have improved the path matching to look for exact matches first before applying the scoring. This should address the problem.
-
reporter Awesome, thanks James! That workaround of swapping the order works for me
-
- changed status to resolved
Available in v2.10.1
- Log in to comment