From 5cb8a96f2d03c5de130979745974a3993eb072dc Mon Sep 17 00:00:00 2001 From: "jonas-lt@live.dk" Date: Wed, 14 Jun 2023 15:04:50 +0200 Subject: [PATCH 1/3] add docs --- .gitignore | 2 +- README.md | 37 ++ docs/ruleset/README.md | 11 + docs/ruleset/core-ruleset.md | 116 +++++ docs/ruleset/recommended-ruleset.md | 238 ++++++++++ docs/ruleset/v2-core-ruleset.md | 581 +++++++++++++++++++++++++ docs/ruleset/v2-recommended-ruleset.md | 296 +++++++++++++ 7 files changed, 1280 insertions(+), 1 deletion(-) create mode 100644 docs/ruleset/README.md create mode 100644 docs/ruleset/core-ruleset.md create mode 100644 docs/ruleset/recommended-ruleset.md create mode 100644 docs/ruleset/v2-core-ruleset.md create mode 100644 docs/ruleset/v2-recommended-ruleset.md diff --git a/.gitignore b/.gitignore index 2c7221588..943fd793b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ node_modules .vscode .DS_Store -/docs +/docs/api.md /coverage /lib /esm diff --git a/README.md b/README.md index d1e9dc95d..3a2939c2c 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,43 @@ Additionally to all the methods declared in the [Parser-API](https://github.com/ - `jsonPath()` which returns the JSON Path of the given object. - `meta()` which returns the metadata of a given object, like a parsed AsyncAPI Document. +## Spectral rulesets + +[Spectral](https://github.com/stoplightio/spectral) powers the validation of AsyncAPI documents within ParserJS. For this reason, it is possible to use your rulesets/rules or overwrite existing ones, passing the `ruleset` option to the Parser instance: + +```ts +import { Parser, stringify, unstringify } from '@asyncapi/parser'; +const parser = new Parser({ + ruleset: { + extends: [], + rules: { + 'asyncapi-defaultContentType': 'off', + 'asyncapi-termsOfService': { + description: 'Info "termsOfService" should be present and non-empty string.', + recommended: true, + given: '$', + then: { + field: 'info.termsOfService', + function: 'truthy', + }, + }, + } + } +}); +// One of diagnostics should have `asyncapi-termsOfService` code with `warning` severity, because we didn't define the `$.info.termsOfService` field. +// Also we should won't see the diagnostics related to the omitted `defaultContentType` field. +const diagnostics = await parser.validate(` + asyncapi: '2.0.0' + info: + title: Example AsyncAPI specification + version: '0.1.0' + channels: {} +`); +``` + +[ParserJS has some built-in Spectral rulesets](./docs/ruleset) that validate AsyncAPI documents and inform on good practices. + + ## Using in the browser/SPA applications The package contains a built-in version of the parser. To use it, you need to import the parser into the HTML file as below: diff --git a/docs/ruleset/README.md b/docs/ruleset/README.md new file mode 100644 index 000000000..7c665bd16 --- /dev/null +++ b/docs/ruleset/README.md @@ -0,0 +1,11 @@ +# AsyncAPI Spectral Ruleset + +ParserJS has some built-in Spectral rulesets that validate AsyncAPI documents and inform about good practices. The distinctions are: + +- [Core Ruleset](./core-ruleset.md) - the core ruleset, which validates the overall structure of the specification (applied for each version, starting with `2.0.0`). +- [Recommended Ruleset](./recommended-ruleset.md) - the recommended ruleset, which verify good practices when writing the specification structure (applied for each version, starting with `2.0.0`). +- [v2 Core Ruleset](./v2-core-ruleset.md) - the core ruleset, which validates the overall structure of the `2.x.x` specifications. +- [v2 Recommended Ruleset](./v2-recommended-ruleset.md) - the recommended ruleset, which verify good practices when writing the `2.x.x` specifications structure. + +> **Note** +> The described rulesets are similar to the one found at https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md. They have been adapted under the rights of the Apache-2.0 license. diff --git a/docs/ruleset/core-ruleset.md b/docs/ruleset/core-ruleset.md new file mode 100644 index 000000000..082598f51 --- /dev/null +++ b/docs/ruleset/core-ruleset.md @@ -0,0 +1,116 @@ +# AsyncAPI Core Ruleset + +The core ruleset, which validates the overall structure of the specification. + +> **Note** +> These rules will apply to each version, starting with `2.0.0`. + +## Rules + +### asyncapi-is-asyncapi + +The input must be a document with a supported version of AsyncAPI. + +#### Good example + +```yaml +asyncapi: 2.0.0 +... +``` + +#### Bad example + +```yaml +openapi: 3.1.0 +... +``` + +```yaml +asyncapi: 2.1.37 +... +``` + +### asyncapi-latest-version + +Checking if the AsyncAPI document is using the latest version. + +#### Good example + +```yaml +asyncapi: 2.6.0 +... +``` + +#### Bad example + +```yaml +asyncapi: 2.5.0 +... +``` + +### asyncapi-document-resolved + +Checking if the AsyncAPI document has a valid resolved (with resolved references) structure based on the specification's JSON Schema. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +channels: + user/signup: + publish: + message: + $ref: '#/components/messages/user' +components: + messages: + user: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +``` + +### asyncapi-document-unresolved + +Checking if the AsyncAPI document has a valid unresolved (with unresolved references) structure based on the specification's JSON Schema. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +channels: + user/signup: + publish: + message: + $ref: '#/components/messages/user' +components: + messages: + user: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +channels: + user/signup: + publish: + $ref: '#/components/x-operations/someOperation' +components: + 'x-operations': + someOperation: {} +``` diff --git a/docs/ruleset/recommended-ruleset.md b/docs/ruleset/recommended-ruleset.md new file mode 100644 index 000000000..e5dd2d481 --- /dev/null +++ b/docs/ruleset/recommended-ruleset.md @@ -0,0 +1,238 @@ +# AsyncAPI Recommended Ruleset + +The recommended ruleset, which verifies good practices when writing the specification structure. + +> **Note** +> These rules will apply to each version, starting with `2.0.0`. + +## Rules + +### asyncapi-id + +AsyncAPI document should have an `id` field. + +#### Good example + +```yaml +asyncapi: 2.0.0 +id: 'urn:some:id' +... +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +... +``` + +### asyncapi-defaultContentType + +AsyncAPI document should have a `defaultContentType` field. + +#### Good example + +```yaml +asyncapi: 2.0.0 +defaultContentType: 'application/json' +... +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +... +``` + +### asyncapi-info-description + +Info `description` should be present and a non-empty string. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 + description: Description of awesome AsyncAPI document +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +``` + +### asyncapi-info-contact + +Info object should have a `contact` object. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 + contact: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +``` + +### asyncapi-info-contact-properties + +Contact object should have `name`, `url`, and `email` fields. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 + contact: + name: API Support + url: www.asyncapi.com/support + email: support@asyncapi.com +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 + contact: + name: API Support +``` + +### asyncapi-info-license + +Info object should have a `license` object. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 + license: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +``` + +### asyncapi-info-license-url + +License object should have a `url` field. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 + license: + name: Apache 2.0 +``` + +### asyncapi-servers + +AsyncAPI document should have a non-empty `servers` object. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: + development: + url: development.gigantic-server.com + description: Development server + protocol: kafka + protocolVersion: '1.0.0' +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +``` + +### asyncapi-unused-component + +A potentially unused component has been detected in the AsyncAPI document. + +> **Warning** +> This rule may identify false positives when linting a specification that acts as a library (a container storing reusable objects, leveraged by other specifications that reference those objects). + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +channels: + user/signup: + publish: + message: + $ref: '#/components/messages/user' +components: + messages: + user: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +channels: + user/signup: + publish: + message: {...} +components: + messages: + unusedMessage: {...} +``` diff --git a/docs/ruleset/v2-core-ruleset.md b/docs/ruleset/v2-core-ruleset.md new file mode 100644 index 000000000..94b91579f --- /dev/null +++ b/docs/ruleset/v2-core-ruleset.md @@ -0,0 +1,581 @@ +# AsyncAPI v2 Core Ruleset + +The core ruleset, which validates the overall structure of the `2.x.x` specifications. + +> **Note** +> These rules will only apply to AsyncAPI `2.x.x` documents. + +## Rules + +### asyncapi2-server-security + +Server `security` values must match a scheme defined in the `$.components.securitySchemes` object. It also checks if there are `oauth2` scopes that have been defined for the given security. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: + production: + url: test.mosquitto.org + security: + - authKey: [] +components: + securitySchemes: + authKey: {...} +``` + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: + production: + url: test.mosquitto.org + security: + - oauth2: ['write:user', 'read:user'] +components: + securitySchemes: + oauth2: + flows: + implicit: + scopes: + 'write:user': '...', + 'read:user': '...', +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: + production: + url: test.mosquitto.org + security: + - notDefined: [] +components: + securitySchemes: + authKey: {...} +``` + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: + production: + url: test.mosquitto.org + security: + - oauth2: ['write:user', 'not:defined'] +components: + securitySchemes: + oauth2: + flows: + implicit: + scopes: + 'write:user': '...', + 'read:user': '...', +``` + +### asyncapi2-server-variables + +All server URL variables should be defined in the `variables` object of the server. They should also not contain redundant variables that do not exist in the server address. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: + production: + url: test.{variable}.mosquitto.org + variables: + variable: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: + production: + url: test.{variable}.mosquitto.org +``` + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: + production: + url: test.{variable}.mosquitto.org + variables: + variable: {...} + redundantVariable: {...} +``` + +### asyncapi2-channel-parameters + +All channel parameters should be defined in the `parameters` object of the channel. They should also not contain redundant parameters that do not exist in the channel address. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +channels: + 'users/{userId}/signedUp': + parameters: + userId: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +channels: + 'users/{userId}/signedUp': {} +``` + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +channels: + 'users/{userId}/signedUp': + parameters: + userId: {...} + redundantParameter: {...} +``` + +### asyncapi2-channel-servers + +Channel servers must be defined in the `servers` object. + +#### Good example + +```yaml +asyncapi: 2.2.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: + production: + url: test.{variable}.mosquitto.org + variables: + variable: {...} +channels: + users/signedUp: + servers: + - production +``` + +#### Bad example + +```yaml +asyncapi: 2.2.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: + production: + url: test.{variable}.mosquitto.org + variables: + variable: {...} +channels: + users/signedUp: + servers: + - development +``` + +### asyncapi2-operation-operationId-uniqueness + +`operationId` must be unique across all the operations (except the ones defined in the components). + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: + publish: + operationId: turnOn + smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: + publish: + operationId: turnOff +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +channels: + smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: + publish: + operationId: turn + smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: + publish: + operationId: turn +``` + +### asyncapi2-operation-security + +Operation `security` values must match a scheme defined in the `$.components.securitySchemes` object. It also checks if there are `oauth2` scopes that have been defined for the given security. + +#### Good example + +```yaml +asyncapi: 2.4.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + security: + - authKey: [] +components: + securitySchemes: + authKey: {...} +``` + +```yaml +asyncapi: 2.4.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + security: + - oauth2: ['write:user', 'read:user'] +components: + securitySchemes: + oauth2: + flows: + implicit: + scopes: + 'write:user': '...', + 'read:user': '...', +``` + +#### Bad example + +```yaml +asyncapi: 2.4.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + security: + - notDefined: [] +components: + securitySchemes: + authKey: {...} +``` + +```yaml +asyncapi: 2.4.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + security: + - oauth2: ['write:user', 'not:defined'] +components: + securitySchemes: + oauth2: + flows: + implicit: + scopes: + 'write:user': '...', + 'read:user': '...', +``` + +### asyncapi2-message-examples + +All examples in message object should follow `payload` and `headers` schemas. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +components: + messages: + someMessage: + payload: + type: string + headers: + type: object + examples: + - payload: foobar + headers: + someHeader: someValue +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +components: + messages: + someMessage: + payload: + type: string + headers: + type: object + examples: + - payload: 2137 + headers: someHeader +``` + +### asyncapi2-message-messageId-uniqueness + +`messageId` must be unique across all the messages (except those one defined in the components). + +#### Good example + +```yaml +asyncapi: 2.4.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: + publish: + message: + messageId: turnOnMessage + smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: + publish: + message: + messageId: turnOffMessage +``` + +#### Bad example + +```yaml +asyncapi: 2.4.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +channels: + smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: + publish: + message: + messageId: turnMessage + smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: + publish: + message: + messageId: turnMessage +``` + +### asyncapi2-tags-uniqueness + +Tags must not have duplicate names (identifiers). + +#### Good example + +```yaml +tags: + - name: "env:production" + - name: "e-commerce" +``` + +#### Bad example + +```yaml +tags: + - name: "e-commerce" + - name: "e-commerce" +``` + +### asyncapi2-schemas + +Custom schema must be correctly formatted from the point of view of the used format. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + message: + payload: + type: object +``` + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + message: + schemaFormat: 'application/vnd.aai.asyncapi;version=2.0.0', + payload: + type: object +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + message: + payload: + oneOf: 'this should be an array' + properties: + name: + if: 'this should be an if' +``` + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + message: + schemaFormat: 'notExisting', + payload: + type: object +``` + +### asyncapi2-schema-default + +`default` objects should be valid against the schema they decorate. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + message: + payload: + type: string + default: 'foobar' +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + message: + payload: + type: string + default: 2137 +``` + +### asyncapi2-schema-examples + +Values of the `examples` array should be valid against the schema they decorate. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + message: + payload: + type: string + examples: ['foobar'] +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +channels: + "user/signup": + publish: + message: + payload: + type: string + examples: ['foobar', 2137] +``` diff --git a/docs/ruleset/v2-recommended-ruleset.md b/docs/ruleset/v2-recommended-ruleset.md new file mode 100644 index 000000000..a2216464b --- /dev/null +++ b/docs/ruleset/v2-recommended-ruleset.md @@ -0,0 +1,296 @@ +# AsyncAPI v2 Recommended Ruleset + +The recommended ruleset, which verify good practices when writing the `2.x.x` specifications structure. + +> **Note** +> These rules will only apply to AsyncAPI `2.x.x` documents. + +## Rules + +### asyncapi2-tags + +AsyncAPI object should have a non-empty `tags` array. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +tags: + - e-commerce +servers: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +``` + +### asyncapi2-server-no-empty-variable + +Server URL variable declarations cannot be empty (e.g., `gigantic-server.com/{}` is invalid). + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: + production: + url: test.{variable}.mosquitto.org + variables: + variable: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: + production: + url: test.{}.mosquitto.org +``` + +### asyncapi2-server-no-trailing-slash + +Server URL should not have a trailing slash. + +Some tooling forgets to strip trailing slashes off when it's joining the `$.servers.[*].url` with channels, and you can get awkward URLs like `mqtt://example.com/broker//pets`. Best to just strip them off yourself. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: + production: + url: example.com/broker +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: + production: + url: example.com/broker/ +``` + +### asyncapi2-channel-no-empty-parameter + +Channel parameter declarations cannot be empty (e.g., `./given/{}` is invalid). + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +channels: + users/{userId}/signedUp: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +channels: + users/{}/signedUp: {...} +``` + +### asyncapi2-channel-no-query-nor-fragment + +Query parameters and fragments shouldn't be used in channel names. Instead, use bindings to define them. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +channels: + users/{userId}/signedUp: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +channels: + users/{userId}/signedOut?query={...}: {...} + users/{userId}/signedOut#hash: {...} +``` + +### asyncapi2-channel-no-trailing-slash + +Keep trailing slashes off of channel names, as it can cause some confusion. Most messaging protocols will treat `example/foo` and `example/foo/` as different things. Keep in mind that tooling may replace slashes (`/`) with protocol-specific notation (e.g.: `.` for AMQP), therefore, a trailing slash may result in an invalid channel name in some protocols. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +channels: + users/{userId}/signedUp: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +channels: + users/{userId}/signedUp/: {...} +``` + +### asyncapi2-operation-operationId + +The `operationId` should be defined in each operation, essentially as an operation reference. Tools may use `operationId` for defining function names, class method names, and even URL hashes in documentation systems. + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: + publish: + operationId: turnOn + smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: + publish: + operationId: turnOff +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +channels: + smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: + publish: + operationId: turn + smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: + publish: {...} # without `operationId` +``` + +### asyncapi2-message-messageId + +The `messageId` should be defined in each message, essentially a message reference. Tools may use `messageId` for defining function names, class method names, and even URL hashes in documentation systems. + +#### Good example + +```yaml +asyncapi: 2.4.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: {...} +channels: + smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: + publish: + message: + messageId: turnOnMessage + smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: + publish: + message: + messageId: turnOffMessage +``` + +#### Bad example + +```yaml +asyncapi: 2.4.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: {...} +channels: + smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: + publish: + message: + messageId: turnMessage + smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: + publish: + message: {...} # without `messageId` +``` + +### asyncapi2-unused-securityScheme + +A potentially unused security scheme has been detected in the AsyncAPI document. + +> **Warning** +> This rule may identify false positives when linting a specification that acts as a library (a container storing reusable objects, leveraged by other specifications that reference those objects). + +#### Good example + +```yaml +asyncapi: 2.0.0 +info: + title: Valid AsyncAPI document + version: 1.0 +servers: + production: + url: test.mosquitto.org + protocol: mqtt + security: + - usedSchema: [] +channels: + ... +components: + securitySchemas: + usedSchema: {...} +``` + +#### Bad example + +```yaml +asyncapi: 2.0.0 +info: + title: Invalid AsyncAPI document + version: 1.0 +servers: + production: + url: test.mosquitto.org + protocol: mqtt +channels: + ... +components: + securitySchemas: + unusedSchema: {...} +``` From a7ced5f0784ccce2bced931b8359bc4fc7abfef0 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Wed, 28 Jun 2023 14:01:59 +0200 Subject: [PATCH 2/3] Update docs/ruleset/README.md Co-authored-by: Sergio Moya <1083296+smoya@users.noreply.github.com> --- docs/ruleset/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ruleset/README.md b/docs/ruleset/README.md index 7c665bd16..cdb573286 100644 --- a/docs/ruleset/README.md +++ b/docs/ruleset/README.md @@ -1,6 +1,6 @@ # AsyncAPI Spectral Ruleset -ParserJS has some built-in Spectral rulesets that validate AsyncAPI documents and inform about good practices. The distinctions are: +ParserJS has some built-in Spectral rulesets that validate AsyncAPI documents and inform about good practices. Those are: - [Core Ruleset](./core-ruleset.md) - the core ruleset, which validates the overall structure of the specification (applied for each version, starting with `2.0.0`). - [Recommended Ruleset](./recommended-ruleset.md) - the recommended ruleset, which verify good practices when writing the specification structure (applied for each version, starting with `2.0.0`). From e9aaca5afc8803226f6ffa3d939877d7ae4d395b Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Wed, 28 Jun 2023 14:26:20 +0200 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Sergio Moya <1083296+smoya@users.noreply.github.com> --- README.md | 4 ++-- docs/ruleset/README.md | 8 ++++---- docs/ruleset/core-ruleset.md | 6 ++++-- docs/ruleset/recommended-ruleset.md | 4 ++-- docs/ruleset/v2-recommended-ruleset.md | 4 ++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 1e254a313..34b1acd69 100644 --- a/README.md +++ b/README.md @@ -248,8 +248,8 @@ const parser = new Parser({ } } }); -// One of diagnostics should have `asyncapi-termsOfService` code with `warning` severity, because we didn't define the `$.info.termsOfService` field. -// Also we should won't see the diagnostics related to the omitted `defaultContentType` field. +// The returned diagnostics object will include `asyncapi-termsOfService` diagnostic with `warning` (`recommended: true`) severity because `$.info.termsOfService` is not defined in the following AsyncAPI document. +// On the other hand, since we turned it off, we won't see the diagnostics related to the `defaultContentType` field. const diagnostics = await parser.validate(` asyncapi: '2.0.0' info: diff --git a/docs/ruleset/README.md b/docs/ruleset/README.md index cdb573286..44f70a10b 100644 --- a/docs/ruleset/README.md +++ b/docs/ruleset/README.md @@ -2,10 +2,10 @@ ParserJS has some built-in Spectral rulesets that validate AsyncAPI documents and inform about good practices. Those are: -- [Core Ruleset](./core-ruleset.md) - the core ruleset, which validates the overall structure of the specification (applied for each version, starting with `2.0.0`). -- [Recommended Ruleset](./recommended-ruleset.md) - the recommended ruleset, which verify good practices when writing the specification structure (applied for each version, starting with `2.0.0`). -- [v2 Core Ruleset](./v2-core-ruleset.md) - the core ruleset, which validates the overall structure of the `2.x.x` specifications. -- [v2 Recommended Ruleset](./v2-recommended-ruleset.md) - the recommended ruleset, which verify good practices when writing the `2.x.x` specifications structure. +- [Core Ruleset](./core-ruleset.md) - validates the overall structure of AsyncAPI documents (applied for each version, starting from `2.0.0`). +- [Recommended Ruleset](./recommended-ruleset.md) - verifies good practices within AsyncAPI documents structure (applied for each version, starting from `2.0.0`). +- [v2 Core Ruleset](./v2-core-ruleset.md) - validates the overall structure of AsyncAPI version `2.x.x` documents. +- [v2 Recommended Ruleset](./v2-recommended-ruleset.md) - verifies good practices within AsyncAPI version `2.x.x` documents. > **Note** > The described rulesets are similar to the one found at https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md. They have been adapted under the rights of the Apache-2.0 license. diff --git a/docs/ruleset/core-ruleset.md b/docs/ruleset/core-ruleset.md index 082598f51..6ce48bb6f 100644 --- a/docs/ruleset/core-ruleset.md +++ b/docs/ruleset/core-ruleset.md @@ -1,9 +1,9 @@ # AsyncAPI Core Ruleset -The core ruleset, which validates the overall structure of the specification. +The core ruleset validates the overall structure of AsyncAPI documents. > **Note** -> These rules will apply to each version, starting with `2.0.0`. +> These rules will apply to each version, starting from `2.0.0`. ## Rules @@ -36,6 +36,8 @@ Checking if the AsyncAPI document is using the latest version. #### Good example +Assuming the latest version is `2.6.0`: + ```yaml asyncapi: 2.6.0 ... diff --git a/docs/ruleset/recommended-ruleset.md b/docs/ruleset/recommended-ruleset.md index e5dd2d481..1cac29fd6 100644 --- a/docs/ruleset/recommended-ruleset.md +++ b/docs/ruleset/recommended-ruleset.md @@ -1,9 +1,9 @@ # AsyncAPI Recommended Ruleset -The recommended ruleset, which verifies good practices when writing the specification structure. +The recommended ruleset verifies good practices within AsyncAPI documents structure. > **Note** -> These rules will apply to each version, starting with `2.0.0`. +> These rules will apply to each version, starting from `2.0.0`. ## Rules diff --git a/docs/ruleset/v2-recommended-ruleset.md b/docs/ruleset/v2-recommended-ruleset.md index a2216464b..7de8c9a4c 100644 --- a/docs/ruleset/v2-recommended-ruleset.md +++ b/docs/ruleset/v2-recommended-ruleset.md @@ -1,6 +1,6 @@ # AsyncAPI v2 Recommended Ruleset -The recommended ruleset, which verify good practices when writing the `2.x.x` specifications structure. +The recommended ruleset verifies good practices within AsyncAPI version `2.x.x` documents. > **Note** > These rules will only apply to AsyncAPI `2.x.x` documents. @@ -9,7 +9,7 @@ The recommended ruleset, which verify good practices when writing the `2.x.x` sp ### asyncapi2-tags -AsyncAPI object should have a non-empty `tags` array. +AsyncAPI document should have a non-empty `tags` array. #### Good example