I'm trying creaiting ruleset for RAML to check if there are the example for responses and description for uriParams.
/example:
/{uriParams}:
get:
uriParameters:
uriParams:
description: Example description uriParams
body:
application/json:
example: !include examples.example.json
And for this I create two ruleset but it's not working:
response-example:
message: Provide example.
targetClass: apiContract.Example
and:
- propertyConstraints:
apiContract.returns:
atLeast:
count: 1
validation:
propertyConstraints:
apiContract.structuredValue:
pattern: "^!include"
uri-descriptions:
message: Provide descriptions.
targetClass: apiContract.Parameter
if:
propertyConstraints:
apiContract.Parameter:
pattern: uri
then:
propertyConstraints:
core.description:
minCount: 1
Checking examples is non-trivial. AMF (RAML parser used for Governance) resolves them to the schema of the parameter, payload, header, etc. Just clarifying with an example: imagine that if you have a response of type Person
and an example there, the example will be transferred from the response to the Person
type.
Fortunately AMF keeps an annotation called tracked-element that points back to the original parameter, payload, header, etc. where the example was defined. Unfortunately checking that these are the same element must be done with custom Rego code.
Here's the resulting ruleset:
profile: My Ruleset
description: Example ruleset
violation:
- provide-examples-on-payloads
- provide-description-on-parameters
validations:
provide-examples-on-payloads:
message: Always include examples in request and response bodies
targetClass: apiContract.Payload
rego: |
schema = find with data.link as $node["http://a.ml/vocabularies/shapes#schema"]
nested_nodes[examples] with data.nodes as object.get(schema, "http://a.ml/vocabularies/apiContract#examples", [])
examples_from_this_payload = { element |
example = examples[_]
sourcemap = find with data.link as object.get(example, "http://a.ml/vocabularies/document-source-maps#sources", [])
tracked_element = find with data.link as object.get(sourcemap, "http://a.ml/vocabularies/document-source-maps#tracked-element", [])
tracked_element["http://a.ml/vocabularies/document-source-maps#value"] = $node["@id"]
element := example
}
$result := (count(examples_from_this_payload) > 0)
provide-description-on-parameters:
message: Always include examples in URI parameters
targetClass: apiContract.Parameter
if:
propertyConstraints:
apiContract.binding:
in: ['path']
then:
propertyConstraints:
core.description:
minCount: 1