{"id":21323185,"url":"https://github.com/schwarzit/api-linter-rules","last_synced_at":"2025-07-12T05:31:23.586Z","repository":{"id":39635052,"uuid":"449710099","full_name":"SchwarzIT/api-linter-rules","owner":"SchwarzIT","description":"Schwarz API rule definitions for the Spectral API linter","archived":false,"fork":false,"pushed_at":"2024-04-30T15:56:54.000Z","size":1082,"stargazers_count":20,"open_issues_count":1,"forks_count":4,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-04-30T17:02:12.255Z","etag":null,"topics":["api","linting-rules","openapi","spectral"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SchwarzIT.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-19T13:48:40.000Z","updated_at":"2024-04-30T15:56:58.000Z","dependencies_parsed_at":"2024-05-06T19:39:33.793Z","dependency_job_id":null,"html_url":"https://github.com/SchwarzIT/api-linter-rules","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SchwarzIT%2Fapi-linter-rules","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SchwarzIT%2Fapi-linter-rules/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SchwarzIT%2Fapi-linter-rules/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SchwarzIT%2Fapi-linter-rules/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SchwarzIT","download_url":"https://codeload.github.com/SchwarzIT/api-linter-rules/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225796611,"owners_count":17525532,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","linting-rules","openapi","spectral"],"created_at":"2024-11-21T20:21:19.115Z","updated_at":"2024-11-21T20:21:19.839Z","avatar_url":"https://github.com/SchwarzIT.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# api-linter-rules\n\n[![SIT](https://img.shields.io/badge/SIT-awesome-blueviolet.svg)](https://jobs.schwarz)\n\nSchwarz API spectral custom rulesets to be used with [Spectral Linter](https://github.com/stoplightio/spectral) toolset. You can use this rules to integrate them in your own development workflow or you can build upon your own interpretation of how an API should look like.\n\nRulesets are based on file inheritance on custom rulesets as supported by [Spectral Rulesets](https://meta.stoplight.io/docs/spectral/ZG9jOjYyMDc0NA-rulesets) assuming that different API types use the same ruleset but different severity levels as provided by [Spectral Custom Rulesets](https://meta.stoplight.io/docs/spectral/ZG9jOjI1MTg5-custom-rulesets). All API type specific rulesets depend on the same [base ruleset file](./spectral.yml) and just overwrite rulesets or severity levels.\n\nRules Wiki and HowTo´s can be found [here](https://github.com/SchwarzIT/api-linter-rules/wiki).\n\nExample how to overwrite severity levels in [spectral-api.yml](./spectral-api.yml):\n\n```yaml\nextends:\n  - https://raw.githubusercontent.com/SchwarzIT/api-linter-rules/main/spectral.yml\nrules:\n  operation-tag-defined: off\n  path-must-match-api-standards: warn\n  servers-must-match-api-standards: warn\n  common-responses-unauthorized: warn\n  no-http-verbs-in-resources: warn\n  description-is-mandatory: warn\n```\n\n***\n\n## Base ruleset\n\n* Base ruleset is defined in [spectral.yml](./spectral.yml)\n* Extends from spectral:oas [recommended rules](https://meta.stoplight.io/docs/spectral/ZG9jOjExNw-open-api-rules)\n* Is generated by merging it with all individual rules at build time\n\n```yml\nextends: [[spectral:oas, recommended]]\n```\n## Supported API Types\n\n* Product API ruleset is defined in [spectral-api.yml](./spectral-api.yml)\n  ```\n  https://raw.githubusercontent.com/SchwarzIT/api-linter-rules/main/spectral-api.yml\n  ```\n* Backend For Frontend is defined in [spectral-bff.yml](./spectral-bff.yml)\n  ```\n  https://raw.githubusercontent.com/SchwarzIT/api-linter-rules/main/spectral-bff.yml\n  ```\n* Legacy API is defined in [spectral-legacy.yml](./spectral-legacy.yml)\n  ```\n  https://raw.githubusercontent.com/SchwarzIT/api-linter-rules/main/spectral-legacy.yml\n  ```\n\n## Local usage in IDE\n\n### Visual Studio Code\n\n* Install [Spectral Linter for VS Code](https://github.com/stoplightio/vscode-spectral)\n* Copy rules in your repo and create VS Code settings as described in the plugin repo OR just reference the desired API type validation from this repository like shown underneath:\n\n1. Create \"spectral.config.yml\" in the root of you repository and paste below content into it\n\n```yaml\nextends:\n- https://raw.githubusercontent.com/SchwarzIT/api-linter-rules/main/spectral-{API_TYPE}.yml\n````\n\n2. Adapt VS Code settings in .vscode/settings.json\n\n```json\n\"spectral.rulesetFile\": \"./spectral.config.yml\",\n\"spectral.validateFiles\": [\n    \"**/openapi/**/*.json\",\n],\n```\n3. Place your open api spec in a folder called \"openapi\"\n\n4. Enjoy API Linting\n\n### Jetbrains IDE family\n\n* Install [Spectral Linter for Jetbrains IDE´s](https://github.com/SchwarzIT/spectral-intellij-plugin)\n\n* Open Jetbrains IDE preferences/tools/spectral and configure source rule set (see API Types above) for API linting and files to be linted\n\n![jetbrains_spectral_config.png](./assets/jetbrains_spectral_config.png)\n\n* Enjoy API linting in Jetbrains IDE family\n\n![jetbrains_spectral_linting.png](./assets/jetbrains_spectral_linting.png)\n\n## Usage in CI\n\nComming soon..\n\n## Usage in API design first approach\n\nComming soon..\n\n## Building\n\nIn order to save on http requests, when using one of the rulesets, the individual rules are not extended but bundled.\nIn a build step all individual rules are collected and merged into the file spectral.yml.\nSplitting our ruleset into individual rules also improves maintainability as well as testing.\n\nFor this the cli tool [yq](https://github.com/mikefarah/yq) is used.\nSo in order to build the rules you need to have it installed locally. (See [installing yq](https://github.com/mikefarah/yq#install))\n\nAlso keep in mind, that the rules are built using bash scripts. So if you're on windows, you might want to use something like GitBash or [WSL](https://docs.microsoft.com/de-de/windows/wsl/about)\n\n### CI\n\nDuring CI the same tool and script is used to merge the Rules.\nAfterwards the script [checkSpectralYaml.sh](./util/scripts/checkSpectralYaml.sh) is executed to find out whether the commited spectral.yml is up to date.\nIf that's not the case, the pipeline fails asking you to build the rules before committing.\nIf [spectral.yml](./spectral.yml) is valid, the api type specific rulesets will be checked. Each of them must specify a severity for every rule inside [spectral.yml](./spectral.yml).\n\n## Testing\n\nTo test our ruleset we decided to split it into individual rulesets containing only one rule.\nAs written above, all individual rules will be merged during build.\nSplitting the ruleset enables us to test each rule isolated from the others.\nTo do this we created a custom [jest-transformer](./util/transforms/spectralRuleTransformer.js) for `.yml` files.\nThat way it's possible to just import an individual rule in a test and use it.\n\nExample:\n\n```ts\nimport { Spectral } from \"@stoplight/spectral-core\";\nimport ruleset from \"./path-must-match-api-standards.yml\";\n\ndescribe(\"path-must-match-api-standards\", () =\u003e {\n  let spectral: Spectral;\n  \n  beforeEach(() =\u003e { spectral = setupSpectral(ruleset); });\n\n  it(\"has a correct path\", async () =\u003e {\n    const result = await spectral.run(`{\"paths\": {\"/api-linting/api/v1/rules\": {}}}`);\n    expect(result).toHaveLength(0);\n  });\n};\n```\n\n[setupSpectral()](./util/jest.setup.ts) is a global utility function that creates a usable Spectral instance from a ruleset.\n\n## Documentation\n\nSince it would be pretty cumbersome to document the wiki pages of this project for all rules, we decided to automate this process.\nOn every push to main the [wiki-pipeline](.github/workflows/wiki-pipeline.yml) checks out the wiki-repo, re-builds the documentation and pushes it to the wiki-repo.\nThe documentation is generated by extracting the head comment of all the individual rules. So a comment like this:\n\n```yaml\n# Comment shown in Wiki description\n# **bold text**\n\nrules:\n  ## Comment shown in source code ##\n  path-must-match-api-standards:\n```\n\nIs turned into a heading with the rule name, the upper comment, the severity levels specified inside the `spectral-*.yml` files and the implementation of the rule.\nIt's even possible to use Markdown inside the head comment like in the example above.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschwarzit%2Fapi-linter-rules","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschwarzit%2Fapi-linter-rules","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschwarzit%2Fapi-linter-rules/lists"}