0

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
aled
  • 21,330
  • 3
  • 27
  • 34
Anonim
  • 81
  • 5

1 Answers1

2

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
  • Do yo know how improve the ruleset to check if the name of uriParameters, queryParameters and endpoind have only camleCase? ``` camel-case-fields: message: Use camelCase for all of the field names. Avoid underscores. targetClass: shacl.PropertyShape if: propertyConstraints: shacl.name: in: ['path'] then: propertyConstraints: shacl.name: pattern: "^[a-z]+([A-Z][a-z]+)*$" ``` – Anonim Jul 15 '22 at 11:08
  • @Anonim yes, you should use the `pattern` constraint. I would suggest starting with a compliant example, generate the AMF model and use that to see what `targetClass` & `propertyConstraints` to target. There's an [AMF CLI tool](https://github.com/aml-org/amf-custom-validator#relation-with-amf) for that – Nicolas Schejtman Jul 18 '22 at 18:34
  • Hi, yes, I was generated the JSON-Ld and it helps a lot but still doesn't work. – Anonim Jul 19 '22 at 08:17
  • Use this as a template: camel-case-fields: message: Use camelCase for all of the field names. Avoid underscores. targetClass: shacl.PropertyShape propertyConstraints: shacl.name: pattern: "^[a-z]+([A-Z][a-z]+)*$" – Nicolas Schejtman Jul 20 '22 at 14:05