Loading…
Loading…
Describes the automated quality analysis service that lints OpenAPI specifications for issues like missing descriptions, naming drift, and invalid
The Specification Linting Service (SpecLintService) is an automated quality analysis tool that assesses OpenAPI v3 specifications. It identifies and reports on stylistic and quality issues that, while not violations of the OpenAPI Specification (OAS) 3.0 standard, can degrade the quality and usability of the published API contract for consumers.
This service acts as a secondary quality gate. It runs after the primary structural conformance check, which already enforces strict OAS 3.0 compliance and fails builds for definitive violations like broken references or duplicate operationIds. The linting service targets more subtle issues such as missing descriptions, untyped schema properties, and deviations from naming conventions.
The service is invoked during the specification generation and activation process. It takes an OpenAPI artifact as input, performs the linting analysis, calculates a quality score, and persists the results. It is designed to be "fail-soft," meaning any failure during the linting or persistence process is logged and does not block the overall spec generation or activation workflow.
The core logic resides in the lintAndStore method, which orchestrates the analysis and persistence of linting results for a given OpenAPI artifact.
flowchart TD
subgraph Spec Generation/Activation Process
A[OpenAPI Artifact Generated] --> B{Call SpecLintService.lintAndStore};
end
subgraph SpecLintService
B --> C{Parse OpenAPI JSON};
C -- Fails --> D[Create 'unparseable-document' finding];
C -- Succeeds --> E{Traverse spec};
E --> F[Apply linting rules];
F --> G[Generate list of findings];
G --> H{Calculate score};
H --> I[Construct SpecLintResult];
I --> J{Persist result via upsert};
end
subgraph Handling
J -- Success --> K[Return SpecLintResult];
J -- Fails --> L[Log warning, return null];
D --> H;
end
A --> M((Database));
K --> M;The process follows these steps:
lintAndStore method is called with an OpenApiArtifactRecord, which contains the OpenAPI specification as a JSON string.unparseable-document finding and proceeds to scoring.SpecLintFinding object is created. This object captures the rule ID, severity, a JSON Path-like location of the issue in the document, and a descriptive message.SpecLintResult object is created, containing the final score, counts of findings by severity, and the complete list of individual findings. This result is then persisted to the database via an upsert operation.lintAndStore is wrapped in an exception handler. If any RuntimeException occurs during linting or persistence, the error is logged, and the method returns null. This ensures that a linting failure never blocks the parent spec generation or activation process.The quality score provides a quantitative measure of the specification's adherence to quality standards.
error: -10 points per findingwarning: -3 points per findinginfo: -1 point per findingThe service applies the following rules during analysis. Each finding includes a stable ruleId for programmatic use.
Rule ID (ruleId) | Severity | Description |
|---|---|---|
unparseable-document | error | The provided document is not a parseable JSON document. |
example-violates-schema | error | An example value provided within a schema violates that schema's own constraints, such as enum, maxLength, or minLength. This is a critical error as it can cause validation failures at the gateway for consumers using the example. |
missing-operation-summary | warning | An operation has neither a summary nor a description. |
missing-schema-type | warning | A schema object lacks a type and does not use $ref or a composition keyword (allOf, anyOf, oneOf), making it an untyped leaf. |
empty-enum | warning | A schema declares an empty enum array (enum: []), which is a useless constraint providing zero alternatives. |
unused-component-schema | warning | A schema is defined in components.schemas but is never referenced ($ref) anywhere in the specification. |
missing-operation-id | info | An operation does not have an operationId. While the platform's conformance guard already enforces this for most specs, this serves as a defense-in-depth check. |
missing-operation-description | info | An operation has a summary but is missing a more detailed description. |
missing-parameter-description | info | A parameter is defined without a description. |
property-naming-drift | info | A property name in a schema is not in camelCase. This checks for adherence to the standard naming convention for JSON keys. |
NOTE
Empty Field Encoding
The platform intentionally supports empty values (e.g., "", {}) in API payloads. The linting service respects this convention and will not flag empty string examples, empty object examples, or enums containing an empty string (enum: [""]). Only a structurally empty enum array (enum: []) is flagged.
NOTE
Naming Convention Exemptions
The property-naming-drift rule exempts certain keys from the camelCase check. Keys beginning with an underscore (_) or x- are considered intentional protocol or extension keys and are not flagged.
The service produces and persists data according to the following models.
This object represents the complete result of a linting operation for a single artifact.
| Field | Type | Description |
|---|---|---|
id | UUID | The unique identifier for this lint result record. |
serviceId | UUID | The ID of the service associated with the linted artifact. |
serviceVersionId | UUID | The ID of the service version associated with the linted artifact. |
artifactSha256 | String | The SHA-256 hash of the linted OpenAPI JSON artifact. |
score | int | The calculated quality score, from 0 to 100. |
errorCount | int | The total number of findings with error severity. |
warningCount | int | The total number of findings with warning severity. |
infoCount | int | The total number of findings with info severity. |
findings | List<SpecLintFinding> | A list of all individual findings discovered during the lint. |
lintedAt | OffsetDateTime | The timestamp when the linting operation was completed. |
This object represents a single quality issue found in the specification.
| Field | Type | Description |
|---|---|---|
ruleId | String | The stable, machine-readable identifier for the rule that was violated. |
severity | String | The severity of the finding: error, warning, or info. |
location | String | A JSON Path-like string indicating where the issue was found in the document. |
message | String | A human-readable message describing the issue. |
The SpecLintService is explicitly designed to never block specification generation or activation. If an unexpected error occurs during its execution, the lintAndStore method will:
null to its caller.The calling process will continue, meaning the specification will still be generated and activated, but no linting result will be persisted for that version.
unparseable-document: This error finding indicates that the input to the linter was not valid JSON. This is a fundamental issue that prevents any further analysis.example-violates-schema: This error finding is critical. It means an example in the specification is invalid according to the schema it is supposed to illustrate. API consumers who copy and use this example in their requests will likely receive validation errors from the API gateway, leading to a poor developer experience.OpenApiService.enforceConformantOas30, which handles strict OAS 3.0 compliance.docs/lld/naming-and-standards.md).