Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(repo): update rulesets docs #2310

Merged
merged 40 commits into from
Oct 27, 2022
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e55f310
docs(repo): update intro to rulesets
heitortsergent Oct 14, 2022
76a8a9a
docs(repo): expand on ruleset introduction
heitortsergent Oct 14, 2022
cfd7647
docs(repo): small update to intro
heitortsergent Oct 14, 2022
5dcd3a8
docs(repo): add section for ruleset properties
heitortsergent Oct 14, 2022
90d8d80
docs(repo): remove JSONPath Plus section
heitortsergent Oct 14, 2022
e9efc34
docs(repo): add create a ruleset section to rulesets
heitortsergent Oct 14, 2022
d6771a2
docs(repo): remove core/custom functions section
heitortsergent Oct 14, 2022
5b99638
docs(repo): split up custom rulesets page
heitortsergent Oct 14, 2022
c890a6b
docs(repo): move formats to custom rulesets
heitortsergent Oct 14, 2022
0baa425
docs(repo): move ruleset properties to custom rulesets
heitortsergent Oct 14, 2022
8783457
docs(repo): move extending rulesets section
heitortsergent Oct 14, 2022
ae825db
docs(repo): move core rulesets section
heitortsergent Oct 14, 2022
8de6fa9
docs(repo): small updates to custom rulesets overview
heitortsergent Oct 17, 2022
6a284b0
docs(repo): update resolved rule example
heitortsergent Oct 18, 2022
54c8344
docs(repo): add lint instruction to rulesets
heitortsergent Oct 18, 2022
b34b79f
docs(repo): add link to other rulesets
heitortsergent Oct 18, 2022
06fedec
docs(repo): reorganize custom rulesets, update intro
heitortsergent Oct 18, 2022
d6dd30d
docs(repo): small clarification for formats
heitortsergent Oct 18, 2022
8d16c4e
docs(repo): remove link
heitortsergent Oct 18, 2022
f55d328
docs(repo): remove unnecessary words
heitortsergent Oct 18, 2022
e6628f6
docs(repo): fix broken link
heitortsergent Oct 18, 2022
797dc90
docs(repo): remove core rulesets section
heitortsergent Oct 18, 2022
00a7b35
docs(repo): update rules section
heitortsergent Oct 18, 2022
d9bc8df
docs(repo): delete rules header and move content
heitortsergent Oct 18, 2022
6b9c576
docs(repo): add properties to ruleset and rules list
heitortsergent Oct 18, 2022
068c1ac
docs(repo): change Rulesets title to Create a Ruleset
heitortsergent Oct 19, 2022
df54b5f
docs(repo): update headings
heitortsergent Oct 19, 2022
b7cba6b
docs(repo): update toc Custom Rulesets to Rulesets
heitortsergent Oct 19, 2022
bcec07d
docs(repo): break up rules into its own page
heitortsergent Oct 19, 2022
dfa5544
docs(repo): cleanup md
heitortsergent Oct 19, 2022
a4ea276
docs(repo): update ruleset properties section
heitortsergent Oct 19, 2022
5546a21
docs(repo): update rules properties
heitortsergent Oct 19, 2022
d5b8de3
docs(repo): rewording
heitortsergent Oct 19, 2022
31eb749
docs(repo): rename files
heitortsergent Oct 20, 2022
f5c83ef
docs(repo): update toc
heitortsergent Oct 20, 2022
bec2378
docs(repo): fix link
heitortsergent Oct 20, 2022
1163371
docs(repo): pam feedback
heitortsergent Oct 21, 2022
6e00e46
Merge branch 'develop' into docs/reorganize-rulesets
heitortsergent Oct 24, 2022
33f4f24
Merge branch 'develop' into docs/reorganize-rulesets
heitortsergent Oct 26, 2022
633608e
Merge branch 'develop' into docs/reorganize-rulesets
heitortsergent Oct 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 34 additions & 135 deletions docs/getting-started/3-rulesets.md
Original file line number Diff line number Diff line change
@@ -1,161 +1,60 @@
# Rulesets
# Create a Ruleset

Rulesets are collections of rules written in JSON, YAML, or [JavaScript](../guides/4-custom-rulesets.md#alternative-js-ruleset-format), which can be used to power powerful linting of other JSON or YAML files. Meta, we know! 😎
Rulesets are collections of rules written in JSON, YAML, or [JavaScript](../guides/4-custom-rulesets.md#alternative-js-ruleset-format), which can be used to power powerful linting of other JSON or YAML files, such as OpenAPI or AsyncAPI descriptions. Meta, we know! 😎

These rules are taking parameters, and calling functions on certain parts of another YAML or JSON object being linted.
Ruleset files are often named `.spectral.yaml`, but that's not a requirement.

## Anatomy of a Ruleset
Rules take certain parameters and then call functions on parts of another YAML or JSON object being linted.

A ruleset is a JSON, YAML, or JavaScript file ([often the file will be called `.spectral.yaml`](../guides/2-cli.md#using-a-ruleset-file)), and there are two main parts.
## Extend an Existing Ruleset

### Rules
The fastest way to create a ruleset is to use the `extends` property to leverage an existing ruleset.

Rules might look a bit like this:
Spectral comes with two built-in rulesets:

```yaml
rules:
paths-kebab-case:
description: Paths should be kebab-case.
message: "{{property}} should be kebab-case (lower-case and separated with hyphens)"
severity: warn
given: $.paths[*]~
then:
function: pattern
functionOptions:
match: "^(\/|[a-z0-9-.]+|{[a-zA-Z0-9_]+})+$"
```

Spectral has [built-in functions](../reference/functions.md) such as `truthy` or `pattern`, which can be used to power rules.

Rules then target certain chunks of the JSON/YAML with the `given` keyword, which is a [JSONPath](http://jsonpath.com/) (actually, we use [JSONPath Plus](https://www.npmjs.com/package/jsonpath-plus)).

The example above adds a single rule that looks at the root level `tags` object's children to make sure they all have a `description` property.

### JSONPath Plus

As mentioned, spectral is using JSONPath Plus which expands on the original JSONPath specification to add some additional operators and makes explicit some behaviors the original did not spell out.

Here are some convenient **additions or elaborations**:

- `^` for grabbing the **parent** of a matching item
- `~` for grabbing **property names** of matching items (as array)
- **Type selectors** for obtaining:
- Basic JSON types: `@null()`, `@boolean()`, `@number()`, `@string()`, `@array()`, `@object()`
- `@integer()`
- The compound type `@scalar()` (which also accepts `undefined` and
non-finite numbers when querying JavaScript objects as well as all of the basic non-object/non-function types)
- `@other()` usable in conjunction with a user-defined `otherTypeCallback`
- Non-JSON types that can nevertheless be used when querying
non-JSON JavaScript objects (`@undefined()`, `@function()`, `@nonFinite()`)
- `@path`/`@parent`/`@property`/`@parentProperty`/`@root` **shorthand selectors** within filters
- **Escaping**
- `` ` `` for escaping remaining sequence
- `@['...']`/`?@['...']` syntax for escaping special characters within
property names in filters
- Documents `$..` (**getting all parent components**)

### Extending Rulesets

Rulesets can extend other rulesets using the `extends` property, allowing you to pull in other rulesets.

```yaml
extends: spectral:oas
```
- `spectral:oas` - [OpenAPI v2/v3 rules](./4-openapi.md)
- `spectral:asyncapi` - [AsyncAPI v2 rules](./5-asyncapi.md)

Extends can reference any [distributed ruleset](../guides/7-sharing-rulesets.md). It can be a single string, or an array of strings, and can contain either local file paths, URLs, or even npm modules.
To create a ruleset that extends both rulesets, open your terminal and run:

```yaml
extends:
- ./config/spectral.json
- https://example.org/api/style.yaml
- some-npm-module # note that this would be treated as any other npm package, therefore it has to be placed under node_modules and have a valid package.json.
```bash
echo 'extends: ["spectral:oas", "spectral:asyncapi"]' > .spectral.yaml
```

The `extends` keyword can be combined with extra rules in order to extend and override rulesets. Learn more about that in [custom rulesets](../guides/4-custom-rulesets.md).

### Formats

Formats are an optional way to specify which API description formats a rule, or ruleset, is applicable to. Currently Spectral supports these formats:

- `aas2` (AsyncAPI v2.x)
- `aas2_0` (AsyncAPI v2.0.0)
- `aas2_1` (AsyncAPI v2.1.0)
- `aas2_2` (AsyncAPI v2.2.0)
- `aas2_3` (AsyncAPI v2.3.0)
- `aas2_4` (AsyncAPI v2.4.0)
- `aas2_5` (AsyncAPI v2.5.0)
- `oas2` (OpenAPI v2.0)
- `oas3` (OpenAPI v3.x)
- `oas3_0` (OpenAPI v3.0.x)
- `oas3_1` (OpenAPI v3.1.x)
- `json-schema` (`$schema` says this is some JSON Schema draft)
- `json-schema-loose` (looks like JSON Schema, but no `$schema` found)
- `json-schema-draft4` (`$schema` says this is JSON Schema Draft 04)
- `json-schema-draft6` (`$schema` says this is JSON Schema Draft 06)
- `json-schema-draft7` (`$schema` says this is JSON Schema Draft 07)
- `json-schema-2019-09` (`$schema` says this is JSON Schema 2019-09)
- `json-schema-2020-12` (`$schema` says this is JSON Schema 2020-12)

Specifying the format is optional, so you can completely ignore this if all the rules you are writing apply to any document you lint, or if you have specific rulesets for different formats. If you'd like to use one ruleset for multiple formats, the `formats` key is here to help.
The newly created ruleset file can then be used to lint any OpenAPI v2/v3 or AsyncAPI descriptions using the `spectral lint` command:

```yaml
rules:
oas3-api-servers:
description: "OpenAPI `servers` must be present and non-empty array."
formats: ["oas3"]
given: "$"
then:
field: servers
function: schema
functionOptions:
schema:
items:
type: object
minItems: 1
type: array
```bash
spectral lint myapifile.yaml
```

Specifying the format is optional, so you can completely ignore this if all the rules you are writing apply to any document you lint, or if you have specific rulesets for different formats.
## Write Your First Rule

Formats can be specified at the ruleset level:
Here's what a ruleset with a single rule might look like:

```yaml
formats: ["oas3"]
rules:
oas3-api-servers:
description: "OpenAPI `servers` must be present and non-empty array."
given: "$"
paths-kebab-case:
description: Paths should be kebab-case.
message: "{{property}} should be kebab-case (lower-case and separated with hyphens)"
severity: warn
given: $.paths[*]~
then:
# ...
function: pattern
functionOptions:
match: "^(\/|[a-z0-9-.]+|{[a-zA-Z0-9_]+})+$"
```

Now all the rules in this ruleset will only be applied if the specified format is detected.

If you'd like to use one ruleset for multiple formats but some rules only apply to one format, you can place the `formats` keyword at the rule level instead:

```yaml
rules:
oas3-api-servers:
description: "OpenAPI `servers` must be present and non-empty array."
formats: ["oas3"]
given: "$"
then:
# ...
oas2-hosts:
description: "OpenAPI `servers` must be present and non-empty array."
formats: ["oas2"]
given: "$"
then:
# ...
```
The example above is a rule that can be used to validate an OpenAPI description. It will look at all the `paths` properties to make sure they are kebab-case (lower-case and separated with hyphens).

Custom formats can be registered via the [JS API](../guides/3-javascript.md), but the [CLI](../guides/2-cli.md) is limited to using the predefined formats.
Breaking down each part of the rule:

## Core Rulesets
- `description` and `message` help users quickly understand what the goal of the rule is
- `severity` help define the importance of following the rule
- The `given` keyword tells Spectral what part of the JSON or YAML file to target by using [JSONPath](http://jsonpath.com/) (Spectral uses [JSONPath Plus](https://www.npmjs.com/package/jsonpath-plus)).
- The `then` property includes the `function` type and options that tells Spectral how to apply the function to the JSON or YAML file, and make sure that the rule is being followed or not. Spectral has a set of [built-in functions](../reference/functions.md) such as `truthy` or `pattern`, which can be used to power rules.

Spectral comes with two rulesets included:
## Next Steps

- `spectral:oas` - [OpenAPI v2/v3 rules](./4-openapi.md)
- `spectral:asyncapi` - [AsyncAPI v2 rules](./5-asyncapi.md)
For more information about creating Rulesets and Rules, see [Custom Rulesets](../guides/4-custom-rulesets.md).

You can also make your own: read more about [Custom Rulesets](../guides/4-custom-rulesets.md).
For more examples of existing rulesets you can use, see [Real-World Rulesets](../../README.md#-real-world-rulesets).
Loading