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)。