-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Validation errors when paths have multiple path parameters #229
Comments
…ltiple path parameters
The pull request number is #230 |
Thank you @rwalle61 for the lightning fast feedback!
Short answer Long answer
Although the spec says (and it already said so when jchook wrote):
Those are exactly the same examples and the spec is very clear: this is no ambiguity (so jchook is wrong). There are plenty of APIs having this non-ambiguity like Elasticsearch (look for "/deployments/{deployment_id}" and "/deployments/_search" in https://cloud.elastic.co/api/v1/api-docs/spec.json). Even the official petstore example has this non-ambiguity (look for "/pet/{petId}" and "/pet/findByStatus" in https://petstore3.swagger.io/). Now, getting back to your question (what is the official definition of paths with "same hierarchy"?), I believe the answer is: function sameHierarchy(oapth1, oapath2) {
const pathParamRegex = /\{[^}]+\}/
return oapth1.replaceAll(pathParamRegex, "{}") == oapth2.replaceAll(pathParamRegex, "{}")
} But I agree with you: the spec is unclear. But it is not the case, otherwise they wouldn't have written this:
To be honest (and not so humble) I'm not sure it is very clear to the authors of the spec. Otherwise they would have been able to state it clearly (and to answer your question) :). Still, I have the feeling that a reasonable approach to this problem has to be implemented. What is wrong in my PR? I'm counting template path elements and not considering their position.
I think there might be an unopinionated solution though (I mean: not "betraying" the spirit of the spec or "over-interpreting" it) and I would be grateful if you could give me your opinion. Proposed solution That solution consists in generalizing this example coming from the spec:
I think, for the sake of conciseness, they should have written this (and it would have been enough to make their point):
But instead spec authors chose to add a common prefix (/pets) and I propose to extend this notion of common prefix.
In that example both paths have a common prefix (/shops/{shopId}/pets) and those prefix are equal in the pretty strict sense defined above (ignoring all path parameter names). Since both path share a common prefix, we are back to the only example clearly stated as non-ambiguous by the spec (a template path vs a concrete path):
And that's it. With this new solution the behavior for this example will still be undecided (but the current PR has an opinion about it):
Since the following paths are unambiguous as well (they are both concrete with a common prefix):
I also propose to extend the algorithm to support this:
But anything beyond (additional path parameters) will lead to unpredicted behavior. What do you think? |
Hi @bfreuden, thanks for your careful research, thought, and implementation - that's the type of contribution we're pleased to see! Here are my thoughts, let me know what you think :) As you say, the official guidance is not precise:
So should we decide which one to use? So far our tool has only implemented official behaviour. This has some benefits:
It could be worth giving up some of these benefits if many users request a particular behaviour. But I'm not sure we know what users want yet. For example, you've suggested 2 ways our tool could behave:
I think both suggestions are reasonable, and probably prefer option 1 because it's simpler - e.g. your first PR is much simpler than the second. @mojito317 originally suggested option 1. And you've suggested both, and now prefer option 2 to 1. If we're not sure which is best, perhaps we shouldn't commit to any of them. That said, I'm very glad you raised this discussion and contributed two great PRs :) I suggest leaving this issue open and seeing if people upvote it or comment, to swing towards any of the suggestions. What do you think? |
Hi @rwalle61, thanks again for the fast and thorough reply! Very appreciated :) I really understand your point: sticking to the spec is a sound position. Let me show you this: https://github.com/bfreuden/openapi-validation-tests
Each of them is implementing this API:
The repo is also containing mocha tests based on chai-openapi-response-validator:
Here is the result:
I agree this is no proof... but it sound surprising that 3 frameworks (implemented by different persons) are able to leverage this spec (indeed: manual spec tests do succeed) while chai-openapi-response-validator has troubles with it. I pushed the experiment a little further with Vert.x: as stated in the OpenAPI specification, it is indeed exhibiting unpredictable behavior with this:
Depending on the declaration order in the spec file it will use the first or the second handler. In the end I am left wondering: have we failed to understand the OpenAPI specification (I believe it is the case)? And how come other people seem to have gotten it right (I don't know)? I will push the experiment a little further (to validate my intuition that the second PR is better) and keep you posted. |
Sorry: I have not answered (good) questions you asked in your last message because I feel I can't for the moment. |
Asked the question on Stackoverflow and got an answer from the 4th top contributor of the OpenAPI-Specification github repo. |
Thanks for raising this on Stackoverflow and in the OpenAPI repo, it'd be awesome if you can get an official OpenAPI answer as to what behaviour we should implement 👍 |
@rwalle61 thanks for commenting my issue in the OpenAPI repo. It would be great to get an official answer indeed! I'm sorry I've been busy these days. I'm putting quotes around "ambiguous" because it is (according to the OpenAPI specification, sensu stricto), but it does not seem to be (according to the tools I've tested so far, and according to an OpenAPI contributor). For the sake of the argument, let's stick to the spec and consider it ambiguous though :). In this case I've come to the conclusion that OpenAPIValidators is opinionated (compared to the OpenAPI spec) since it is definitely choosing a path: it is choosing the last matching OA path appearing in the OpenAPI spec of the API. Why is it so? :) OpenAPIValidators could, for instance, refuse to validate the response and report the ambiguity of the spec of the API: this would probably be the most unopinionated and sanest approach. Let's get back to goal the the library (I'm quoting the readme):
The library is not claiming to be an "OpenAPI specification file" validator (it wouldn't need to validate HTTP responses to serve this purpose anyway). It's meant to ease the validation of server behavior. Since we both agree on the fact that the OpenAPI specification is not clear enough (and is openly leaving room for interpretation to implementations), and since the library is meant to help the validation of servers (that do have their own interpretation of the OpenAPI spec), it seems to me that the library should provide ways to mitigate those corner cases. So I'm wondering: could OpenAPIValidators support different ambiguity resolution strategies? For the moment there is only one of them: last. |
Thanks @bfreuden, sorry I've been too busy to reply recently. Sounds like we're not getting a strong official OpenAPI answer. Mike's reply to your Stack Overflow question suggests we should match most-concrete. But to adapt your example, given this spec
A request I think your idea of same hierarchy may cover most cases intuitively. For example, given this spec:
Request I still think that users needing different matching strategies (most-concrete and same-hierarchy) should probably design their API more simply. We could allow the user to configure different matching strategies for our validator, but it feels a lot of complexity for little gain. But how about this - if anyone can list 3 popular OpenAPI APIs (e.g. Swagger PetStore, Elasticsearch) that our validator doesn't match correctly (with current resolution strategy last), then I'll accept we need to change our validator to whatever resolution strategy satisfies the APIs. |
Hi @rwalle61 Well... to be honest I've suggested the multiple matching strategies approach because you seem very concerned about regressions for existing OpenAPIValidators users. I don't think it is necessary though: the same prefix strategy will perform precisely the same way as the current latest strategy for people having a "simple" API (I'm quoting "simple" because I'm referring to your "more simply" statement). And that's logical: the concrete vs abstract case mentioned in the spec is just a specific case of same prefix. Don't get me wrong: I don't think the same prefix strategy is better (in terms of spec compliance) than latest, but I don't think the lastest strategy is better than same prefix neither. However, as suggested by Mike Ralphson's reply, I strongly believe that same prefix is more useful. On top of that it is not that complex (it's only 20 lines of code that are already in my second pull request :)). Concerning the 3 popular APIs, I accept the challenge ! :) Elasticsearch
Kairntech Sherpa
As you can see our API is inpired from Elastic's. Joke API
Joke API is in the top 50 at position 35 :) https://rapidapi.com/LemmoTresto/api/joke3/specs
To conclude on a more serious tone: you're the boss here and I accept that but I won't be able to argue more than I did. Up to you :) |
It looks like it's been some time since this has been looked at and I just wanted to see if it had been fixed or planned to be fixed? |
Which package are you using?
chai-openapi-response-validator
OpenAPI version
3
Describe the bug
When finding the OAPath matching a request path, the validator does not take into account the number of path parameters.
For the moment it only checks the existence of path parameters: OAPaths having no path parameters are favored over templated OAPaths (paths with path parameters).
To Reproduce
Create an API like this:
Depending on the declaration order of paths in the spec, a request like
POST /shops/12345/pets/_search
, might unexpectedly raise a validation error like this:Request operations found for path '/shops/{shop}/pets/{pet}' in API spec: POST
Indeed: there is only a GET here.
That's because the current strategy based on the existence of path parameters does not work here since both paths are templated paths.
Expected behavior
I expect the library to realize that
/shops/{shop}/pets/_search
was called and not to throw any validation error.Are you going to resolve the issue?
Yes: I have already written 2 tests (one for
chai-openapi-response-validator
and one forjest-openapi
) based on thepreferNonTemplatedPathOverTemplatedPath.test.ts
tests and I have corrected the code.The text was updated successfully, but these errors were encountered: