linting API和靜態分析
1)為什麼linting API
API是團隊與外部集成商之間的合同。Linting和靜態分析:- 防止不兼容和隱含的更改;
- 統一狀態,錯誤,分離,安全;
- 使規格可機器驗證,版本可預測;
- 降低了咆哮的成本,縮短了登山時間。
原則: "合同自動審查;沒有綠色林廷的公關不會崩潰。"
2)林廷設施
1.合同:OpenAPI/AsyncAPI/GraphQL SDL,Protobuf/Avro/JSON Schema。
2.實現:REST/gRPC筆,middleware,狀態代碼/標題。
3.基礎架構:安全標題、限制、緩存策略。
4.相關工件:示例(示例),Postman集合,錯誤圖。
3) HTTP API的基本規則(推薦配置文件)
3.1表示法和URL
snake_case在JSON體內,在路徑中使用kebab-case或統一的kebab-case /'/v1/……'。
資源是復數:「/v1/payments」,嵌套為「/v1/wallets/{id}/transactions」。
標識符為path params: '/v1/payments/{payment_id}(類型:string, formating: uuid)。
3.2方法與狀態
「GET」-200/206;「POST」-201(+「位置」),沖突-409;驗證-422;限值為429(+「Retry-After」)。
不要返回200錯誤。條件查詢是「If-None-Match」下的304。
3.3錯誤(單一格式)
json
{ "code":"validation_error", "message":"amount must be ≥ 1", "trace_id":"...", "details":[{"field":"amount","reason":"min:1"}] }
強制性:「code」,「message」,「trace_id」;本地-通過「內容語言」。
3.4分離/過濾器
Cursor-based: `page_size`, `page_token`, ответ: `next_page_token`.
過濾器和排序是在「參數」中記錄的惠特主義者。
3.5安全性
單項安全方案:OAuth2/OIDC scopes或mTLS;禁止「http」(僅「https」)。
不要返回敏感的標題,在示例中掩蓋令牌。
3.6限制和尺寸
標題/身體限制:413/414/431;記錄最大有效值。
4)工具和生態系統
4.1 OpenAPI
Spectral(JSON/YAML lint),Redocly linter,oas-diff/openapi-diff(semantic diff),schemathesis/dredd(執行檢查)。
4.2 Protobuf/gRPC
buf(lint+breaking check),protolint,SDK生成器;gnostic用於分析。
4.3 GraphQL
graphql-schema-linter, graphql-inspector (breaking).
4.4代碼林特和SAST
ESLint,golangci-lint,Detekt/Ktlint,Pylint/Flake8,Semgrep(API氣味和安全模式)。
5)規則示例: Spectral/Redocly
5.1 Spectral(示例'spectral。yaml`)
yaml extends: ["spectral:oas", "spectral:asyncapi"]
rules:
openapi-tags: off info-contact: error no-http: error path-kebab-case:
description: "Paths must be kebab-case"
given: "$.paths[]~"
severity: error then:
function: pattern functionOptions: { match: "^/(?:[a-z0-9]+(?--[a-z0-9]+)/?)+$" }
response-error-schema:
description: "Error responses must use standard schema"
given: "$.paths[][].responses[?(@property >= '400')]"
then:
field: "content.application/json.schema.$ref"
function: truthy id-as-uuid:
given: "$..parameters[?(@.name =~ /.id$/i)]"
then:
field: schema.format function: enumeration functionOptions: { values: ["uuid"] }
5.2 Redocly(片段'.redocly.yaml`)
yaml apis:
main: openapi.yaml lint:
extends:
- recommended rules:
no-ambiguous-paths: error operation-2xx-only: off operation-success-response:
severity: error where:
subject: response filterInParentKeys: ["200","201","204"]
operation-security-defined: error no-plain-http: error
6) Protobuf/gRPC: buf配置文件
6.1 `buf.yaml`
yaml version: v2 modules:
- path: proto lint:
use:
- DEFAULT except:
- PACKAGE_VERSION_SUFFIX # используем v1 в package breaking:
use:
- WIRE_JSON deps: []
建議:
- 不要重新使用字段號;可刪除的-在「保留」中。
- 新字段是「選擇性」或默認字段;不要更改類型/語義。
7)語義diff和「打破」更改
7.1 HTTP
突破示例:- 更改字段的類型/強制性;
- 刪除狀態/路由/參數;
- enum/範圍縮小;
- 更改id格式(uuid → string)。
- 添加可選字段;
- 不影響快樂路徑的新狀態(例如,記錄為「422」);
- enum擴展。
7.2 gRPC/Protobuf
刪除沒有「保留」的字段/更改號碼是斷開。
類型更改(int32 →字符串)-斷開。
將新標簽添加為選項-通常是安全的。
8)合同和代碼聯網
通過兩個線程提供一致性:1.合同→代碼:SDK/服務器存根生成,測試中的負面示例。
2.代碼→合同:規範測試,自動狀態檢查/標頭。
Semgrep想法:- 禁止'error!=nil'時的'return 200';
- 在寫作支付路線上強制執行「Idempotency-Key」;
- 在日誌中掩蓋令牌。
9) CI/CD管線(參考)
pre-commit: spectral lint, redocly lint
PR gate: openapi-diff (base..PR), buf breaking-check, graphql-inspector build: schemathesis smoke, unit/integration linters (ESLint/golangci-lint)
release: publish contracts (artifact/broker), sign & tag
如果:
- 有破折號;
- 違反基本規則(狀態/安全/錯誤);
- 缺少示例/參數說明。
10)規則目錄(您的組織模板)
ID和類型
`_id` — `string`, `format: uuid`.
現金領域是帶有規模的「弦樂」/「decimal」;貨幣是ISO-4217。
錯誤
單一方案(請參見第3節。3),編碼:「400/401/403/404/409/422/429/5xx」。
始終為429/503的「trace_id」;「Retry-After」。
分離
只有cursor;max'page_size'已被記錄下來。
安全性
所有操作均為「安全」塊;描述了「scopes」。
沒有「http: 」鏈接;TLS 1.2+.
緩存/等效性
Для GET — `ETag/Last-Modified`;寫作-「Idempotency-Key」(如果適用)。
文件編制
「摘要」,「描述」,查詢/響應示例(有效性)。
11)自動檢查示例
11.1驗證強制性安全標頭(Spectral)
yaml security-headers:
given: "$.paths[][].responses['200'].headers"
then:
function: truthy
11.2 openapi-diff(偽CI步驟)
openapi-diff --fail-on-incompatible base.yaml pr.yaml
11.3 buf breaking-check
buf breaking --against '.git#branch=main'
12)合同質量可觀察性
度量標準:林廷誤差的公關比例,虛假時間,破折號次數以及規則下的「債務」。
Dashbords:遷移到統一錯誤方案,示例覆蓋,版本穩定性的進展。
13)反模式
「Doc」與代碼分開→分步。將合同保持在服務附近,並發布經過驗證的人工制品。
Linter僅手動。需要一個艱難的公關門。
隨機示例(非確定性)是檢查中的長笛。
沒有負面的例子和錯誤代碼。
重印每項服務的錯誤模式。
忽略Protobuf斷裂檢查(將標簽「更改為眼睛」)。
14) iGaming/財務細節
現金領域-固定規模/四舍五入;禁止浮動。
強制性標題「X-Tenant」,「X-Region」和「traceparent」跟蹤。
支付寫作筆:檢查「Idempotency-Key」,「Retry-After」和正確的409/201語義。
PSP/KYC:HMAC/mTLS webhooks在「securitySchemes」中進行了描述;反復制(「X-Timestamp」,窗口)。
區域限制和錯誤本地化(「內容語言」)。
15)準備就緒支票清單
- Spectral/Redocly配置文件已設計並連接到pre-comit和PR-gate中。
- 單一錯誤圖和狀態-記錄和驗證。
- openapi-diff/GraphQL Inspector/buf-阻止斷裂更改。
- 請求/答復的例子是有效的;分離/過濾器記錄。
- SecuritySchemes和scopes已滿;沒有http鏈接。
- 對於Protobuf:已刪除標簽上的「保留」;新字段是可選的。
- Semgrep/linter代碼包括在內;在日誌中掩蓋秘密。
- CI發布合同文物和林廷報告。
- Playbook:如何在斷裂誹謗(rollback,hotfix,通知集成商)中采取行動。
16) TL;DR
實施自動合約(Spectral/Redocly, buf/GraphQL Inspector)和語義diff,記錄單個錯誤/狀態/分離/安全圖,連接PR門並將合同發布為偽影。任何破折號都是停止信號。對於金錢/付款-特殊規則(等效性,「Retry-After」,HMAC/mTLS)。