belgif / rest-guide-validator

A validator that checks compliance of OpenAPI documents with the Belgif REST guide
Apache License 2.0
5 stars 0 forks source link

Implemented JSON output processor #27

Closed smals-mavh closed 5 days ago

smals-mavh commented 6 days ago

@pvdbosch could you please review?

Example output:

{
  "violationCount" : 10,
  "ignoredViolationCount" : 0,
  "groupedBy" : "RULE",
  "violations" : [ {
    "group" : "[cod-design]",
    "occurrences" : 1,
    "violations" : [ {
      "ruleName" : "[cod-design]",
      "description" : "New code types SHOULD be represented as string values in lowerCamelCase.",
      "message" : null,
      "type" : "MANDATORY",
      "fileName" : "logo.yaml",
      "lineNumber" : 15,
      "pointer" : "/components/schemas/LogoMetaData/properties/mediaType"
    } ]
  }, {
    "group" : "[err-problem]",
    "occurrences" : 1,
    "violations" : [ {
      "ruleName" : "[err-problem]",
      "description" : "Each error response of each operation SHOULD have a media type \"application/problem+json\"",
      "message" : "[Operation: GET /health]",
      "type" : "MANDATORY",
      "fileName" : "openapi.yaml",
      "lineNumber" : 518,
      "pointer" : "/paths/health/get/responses/500"
    } ]
  }, {
    "group" : "[evo-object]",
    "occurrences" : 5,
    "violations" : [ {
      "ruleName" : "[evo-object]",
      "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
      "message" : null,
      "type" : "MANDATORY",
      "fileName" : "openapi.yaml",
      "lineNumber" : 156,
      "pointer" : "/paths/organizations/post/requestBody/content/application/json"
    }, {
      "ruleName" : "[evo-object]",
      "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
      "message" : null,
      "type" : "MANDATORY",
      "fileName" : "openapi.yaml",
      "lineNumber" : 187,
      "pointer" : "/paths/organizations/{enterpriseNumber}/get/responses/200/content/application/json"
    }, {
      "ruleName" : "[evo-object]",
      "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
      "message" : null,
      "type" : "MANDATORY",
      "fileName" : "openapi.yaml",
      "lineNumber" : 223,
      "pointer" : "/paths/organizations/{enterpriseNumber}/put/requestBody/content/application/json"
    }, {
      "ruleName" : "[evo-object]",
      "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
      "message" : null,
      "type" : "MANDATORY",
      "fileName" : "openapi.yaml",
      "lineNumber" : 232,
      "pointer" : "/paths/organizations/{enterpriseNumber}/put/responses/200/content/application/json"
    }, {
      "ruleName" : "[evo-object]",
      "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
      "message" : null,
      "type" : "MANDATORY",
      "fileName" : "openapi.yaml",
      "lineNumber" : 262,
      "pointer" : "/paths/organizations/{enterpriseNumber}/patch/responses/200/content/application/json"
    } ]
  }, {
    "group" : "[hdr-case]",
    "occurrences" : 1,
    "violations" : [ {
      "ruleName" : "[hdr-case]",
      "description" : "By convention, HTTP headers SHOULD use Kebab-Case with uppercase for readability and consistency. ",
      "message" : null,
      "type" : "MANDATORY",
      "fileName" : "openapi.yaml",
      "lineNumber" : 365,
      "pointer" : "/paths/logos/{id}/get/parameters/1"
    } ]
  }, {
    "group" : "[jsn-naming]",
    "occurrences" : 1,
    "violations" : [ {
      "ruleName" : "[jsn-naming]",
      "description" : "All JSON property names SHOULD be written in lowerCamelCase notation.",
      "message" : "[propertyName: Image]",
      "type" : "MANDATORY",
      "fileName" : "logo.yaml",
      "lineNumber" : 24,
      "pointer" : "/components/schemas/Logo"
    } ]
  }, {
    "group" : "[oas-exampl]",
    "occurrences" : 1,
    "violations" : [ {
      "ruleName" : "[oas-exampl]",
      "description" : "Example does not validate against schema",
      "message" : "employerId: Type expected 'integer', found 'string'. In Schema: employer.yaml#/components/schemas/Employer : <belgif/employment/identifier/v1/employment-identifier-v1.yaml#/components/schemas/EmployerId>.<type>\nemployerId: Value '164893015' does not match format 'int64'. In Schema: employer.yaml#/components/schemas/Employer : <belgif/employment/identifier/v1/employment-identifier-v1.yaml#/components/schemas/EmployerId>.<format>",
      "type" : "MANDATORY",
      "fileName" : "employer.yaml",
      "lineNumber" : 40,
      "pointer" : "/components/schemas/Employer/example"
    } ]
  } ]
}

@jpraet and @pvdbosch , could you provide feedback on the output format / structure?

pvdbosch commented 6 days ago

Below a proposed modified output JSON format, more compliant with the REST guide:

{
  "totalViolations": 10,
  "totalIgnoredViolations" : 0,
  "groupedBy" : "rule",
  "violations" : {
    "[cod-design]": {
      "total": 1,
      "occurrences" : [ {
        "ruleId" : "[cod-design]",
        "description" : "New code types SHOULD be represented as string values in lowerCamelCase.",
        "type" : "mandatory",
        "fileName" : "logo.yaml",
        "lineNumber" : 15,
        "pointer" : "/components/schemas/LogoMetaData/properties/mediaType"
      } ]
    },
    "[evo-object]": {
      "total" : 5,
      "occurrences" : [ {
        "ruleId" : "[evo-object]",
        "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
        "type" : "mandatory",
        "fileName" : "openapi.yaml",
        "lineNumber" : 156,
        "pointer" : "/paths/organizations/post/requestBody/content/application/json"
      }, {
        "ruleId" : "[evo-object]",
        "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
        "type" : "mandatory",
        "fileName" : "openapi.yaml",
        "lineNumber" : 187,
        "pointer" : "/paths/organizations/{enterpriseNumber}/get/responses/200/content/application/json"
      }, {
        "ruleId" : "[evo-object]",
        "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
        "type" : "mandatory",
        "fileName" : "openapi.yaml",
        "lineNumber" : 223,
        "pointer" : "/paths/organizations/{enterpriseNumber}/put/requestBody/content/application/json"
      }
      ]
    }
  }
}
smals-mavh commented 6 days ago

Implemented feedback. Example:

{
  "totalViolations" : 10,
  "totalIgnoredViolations" : 0,
  "groupedBy" : "rule",
  "violations" : {
    "[cod-design]" : {
      "total" : 1,
      "occurrences" : [ {
        "ruleId" : "[cod-design]",
        "description" : "New code types SHOULD be represented as string values in lowerCamelCase.",
        "type" : "mandatory",
        "fileName" : "logo.yaml",
        "lineNumber" : 15,
        "pointer" : "#/components/schemas/LogoMetaData/properties/mediaType"
      } ]
    },
    "[err-problem]" : {
      "total" : 1,
      "occurrences" : [ {
        "ruleId" : "[err-problem]",
        "description" : "Each error response of each operation SHOULD have a media type \"application/problem+json\"",
        "message" : "[Operation: GET /health]",
        "type" : "mandatory",
        "fileName" : "openapi.yaml",
        "lineNumber" : 518,
        "pointer" : "#/paths/health/get/responses/500"
      } ]
    },
    "[evo-object]" : {
      "total" : 5,
      "occurrences" : [ {
        "ruleId" : "[evo-object]",
        "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
        "type" : "mandatory",
        "fileName" : "openapi.yaml",
        "lineNumber" : 156,
        "pointer" : "#/paths/organizations/post/requestBody/content/application/json"
      }, {
        "ruleId" : "[evo-object]",
        "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
        "type" : "mandatory",
        "fileName" : "openapi.yaml",
        "lineNumber" : 187,
        "pointer" : "#/paths/organizations/{enterpriseNumber}/get/responses/200/content/application/json"
      }, {
        "ruleId" : "[evo-object]",
        "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
        "type" : "mandatory",
        "fileName" : "openapi.yaml",
        "lineNumber" : 223,
        "pointer" : "#/paths/organizations/{enterpriseNumber}/put/requestBody/content/application/json"
      }, {
        "ruleId" : "[evo-object]",
        "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
        "type" : "mandatory",
        "fileName" : "openapi.yaml",
        "lineNumber" : 232,
        "pointer" : "#/paths/organizations/{enterpriseNumber}/put/responses/200/content/application/json"
      }, {
        "ruleId" : "[evo-object]",
        "description" : "In a request or response body, if any, you MUST always return a JSON object (and not e.g. an array) as a top level data structure to support future extensibility. ",
        "type" : "mandatory",
        "fileName" : "openapi.yaml",
        "lineNumber" : 262,
        "pointer" : "#/paths/organizations/{enterpriseNumber}/patch/responses/200/content/application/json"
      } ]
    },
    "[hdr-case]" : {
      "total" : 1,
      "occurrences" : [ {
        "ruleId" : "[hdr-case]",
        "description" : "By convention, HTTP headers SHOULD use Kebab-Case with uppercase for readability and consistency. ",
        "type" : "mandatory",
        "fileName" : "openapi.yaml",
        "lineNumber" : 365,
        "pointer" : "#/paths/logos/{id}/get/parameters/1"
      } ]
    },
    "[jsn-naming]" : {
      "total" : 1,
      "occurrences" : [ {
        "ruleId" : "[jsn-naming]",
        "description" : "All JSON property names SHOULD be written in lowerCamelCase notation.",
        "message" : "[propertyName: Image]",
        "type" : "mandatory",
        "fileName" : "logo.yaml",
        "lineNumber" : 24,
        "pointer" : "#/components/schemas/Logo"
      } ]
    },
    "[oas-exampl]" : {
      "total" : 1,
      "occurrences" : [ {
        "ruleId" : "[oas-exampl]",
        "description" : "Example does not validate against schema",
        "message" : "employerId: Type expected 'integer', found 'string'. In Schema: employer.yaml#/components/schemas/Employer : <belgif/employment/identifier/v1/employment-identifier-v1.yaml#/components/schemas/EmployerId>.<type>\nemployerId: Value '164893015' does not match format 'int64'. In Schema: employer.yaml#/components/schemas/Employer : <belgif/employment/identifier/v1/employment-identifier-v1.yaml#/components/schemas/EmployerId>.<format>",
        "type" : "mandatory",
        "fileName" : "employer.yaml",
        "lineNumber" : 40,
        "pointer" : "#/components/schemas/Employer/example"
      } ]
    }
  }
}
pvdbosch commented 5 days ago

@jpraet , does the format in last example of @smals-mavh seem OK for you?

'type' property will still be renamed to 'level' in the output

jpraet commented 5 days ago

Yes, output format looks good to me.