Replies: 2 comments
-
As a follow-up, I just tested this with one of the built-in oas rules, oas2-anyOf, which is designed to detect the word "anyOf" in an OAS2 document: "oas2-anyOf": {
"description": "OpenAPI v3 keyword `anyOf` detected in OpenAPI v2 document.",
"message": "anyOf is not available in OpenAPI v2, it was added in OpenAPI v3",
"recommended": true,
"formats": ["oas2"],
"type": "validation",
"given": "$..anyOf",
"then": {
"function": "undefined"
}
}, I then added anyOf to Example 3 above and made it an OAS2 document: 38. schema:
39. $ref: '#/Location1'
40.
41. Location1:
42. anObjectName:
43. $ref: '#/Location2'
44.
45. Location2:
46. BadCamelCase:
47. type: string
48. anyOf:
49. type: string And this is what the terminal prints using the oas2-anyOf rule:
Since this rule does a thorough search for the word "anyOf", it seems to be finding it in two places: Location1.anObjectName.anyOf and Location2.anyOf. But because the complete path isn't listed for the first warning, the linter doesn't realize that the first instance of "anyOf" is actually in the exact same place as the second instance, and thus it doesn't perform the de-duplication. Is there a way to make a change, either in Spectral or in our work, so that the path to "anyOf" would be properly referenced in both searches? |
Beta Was this translation helpful? Give feedback.
-
I think this problem is fixed by this PR: #2202 |
Beta Was this translation helpful? Give feedback.
-
We've been having some trouble applying custom rules to API's that have several $ref's in them. Our linter still has an internal path to the true error that it can use for all other intents and purposes (like for use inside the rule functions), but in the message that prints to the console, the location is presented on an incomplete path. This is sometimes eliminating errors when there are multiple problems on similar deep paths. Below are a few examples that I hope can help illustrate our problem.
Example 1
We made a rule function to enforce camel case on several words in an API. Below is a snippet from an API that we used to test it:
On line 42, the word "BadCamelCase" is not written in proper camel case, so the our rule is written to flag it as an error. It will be found by following the reference on line 39 and reaching the word in the object "Location1" on line 41. This is the terminal output when the camel case rule is run on the above API:
This correctly references line 42, the actual location in the document of the erroneous word. The entire path through the object to find this word is much lengthier, but the path has been successfully converted into one the human can follow to find the word in the document, since a $ref is involved.
Example 2
The next example is similar to the first example, but the path to the erroneous word will involve two references using the $ref keyword. The example snippet is below:
The internal path to the word "BadCamelCase" does not change, since references are not part of the internal path name and the human path to the word goes directly from a reference to Location1 to a reference to Location2. Below is the terminal output when the rule is run against this API:
This correctly references Line 45 and the path "Location2.BadCamelCase", exactly where the human is expected to find the erroneous word.
Example 3
Example 3 will introduce a more problematic API:
On Line 42, the object "anObjectName" is introduced. This complicates the path to the word "BadCamelCase", as the linter must first pass through schema (Line 38), follow the reference to Location1, look in the object "anObjectName", then follow the reference to Location2. Below is the terminal output when the word is run on this API:
The internal path still points all the way to "BadCamelCase", but when generating a human-readable path, our linter stops at "anObjectName" and does not follow the second reference.
Example 4
Example 4 will demonstrate why this inability to follow references to objects with references is a problem for us:
In this example, Location2 contains two words with bad camel case. Both need to be flagged by the linter. Below is our terminal output when the rule is run against the above API:
This seems to be caused by optimization behavior that only allows one error to be returned for a given location. Since this $ref situation causes both BadCamelCase and ReallyBadCamelCase to be perceived as being in the same location (Location1.anObjectName), only is ever flagged during the same run of the linter.
This is leading to problems with some of our larger API's where not nearly enough errors are being printed. But we've noticed that some of the built-in Spectral rules (like "parser" for ensuring response codes are written as strings) are able to successfully lint through nested $ref's and point to the correct location in a yml document. Is there a setting within Spectral or in custom rules that controls how $ref's are handled?
Beta Was this translation helpful? Give feedback.
All reactions