API 产品门户与分析:从消费者订阅到退订和数据删除
一个合作方在开发者门户里点击退订,页面显示操作成功,旧 API Key 却还能调用订单接口;另一个团队删除了消费者账号,分析平台里仍保留可反查到企业名称的 Application、Subscription 和查询参数。前一个问题是撤销状态没有传播到所有数据面,后一个问题是“删除登录账号”被误当成完整的数据删除。
API 产品门户连接的是一条消费生命周期:生产者把可调用能力组织成产品和 Plan,消费者通过 Application 申请 Subscription,平台签发凭据并执行配额,文档帮助完成接入,分析数据反过来支撑运营、容量和审计。门户 UI 只是这条链的一个入口;选用 Gravitee、Kong、Tyk、Azure API Management、Apigee 或自定义 Portal,都要能证明每个对象的 owner、状态、权限、保留期和退出动作。
Portal 管的是 API 消费关系
API 产品不是服务目录条目。服务目录回答“系统由谁负责、代码和运行资源在哪里、依赖关系是什么”;API 产品回答“哪些消费者能按什么条件调用哪些 API、如何取得凭据、额度如何计算、使用数据由谁可见、怎样终止关系”。通用软件目录、Golden Path、脚手架和团队主页解决交付发现问题;API 产品则把已经批准的 API 契约包装成可订阅的消费单元。
不同实现的名词并不统一,先把概念映射到稳定对象,再落到产品字段:
| 稳定对象 | 它回答的问题 | 常见但不保证等价的实现名 |
|---|---|---|
| API / Product | 消费者究竟获得哪些 operation 与环境 | API、Product、Bundle、Catalog item |
| Consumer | 哪个组织或人员承担使用责任 | User、Developer、Organization、Team |
| Application / Client | 哪个工作负载持有凭据 | Application、App、Client、Consumer |
| Plan | 身份方式、审批、额度和使用条件是什么 | Plan、Usage plan、Product policy、Package |
| Subscription | 谁申请了哪个 Plan,当前处于什么状态 | Subscription、Entitlement、Membership |
| Credential | 数据面如何识别这次调用 | API Key、client credential、certificate、JWT issuer binding |
| Analytics event | 谁调用了什么,结果和成本如何 | Access log、API analytics、usage event、metric |
Application 很关键:它把人的登录身份和实际工作负载分开。人员离职不应让生产客户端立即失效,工作负载退役也不应删除整个组织账号。一个 Application 只能代表清楚的系统、环境和 owner;把整个公司所有调用都塞进一个 Key,会让配额、撤销、审计和成本归属同时失真。
对象之间还要有明确的所有权边界。Product owner 决定可消费的 operation 与版本,Plan owner 决定审批、身份和额度,Consumer owner 对组织成员负责,Application owner 对实际工作负载和轮换窗口负责。Portal 管理员可以维护展示与流程,但不能绕过 Product/Plan 直接扩大数据面授权。Azure API Management 的 Subscription 可以绑定 Product、单个 API 或更大 scope,并持有一对主次 Key;Apigee 则要求 Developer App 的 Credential 关联 API Product,且代理实际执行 VerifyAPIKey、OAuth 或 JWT 等策略后,产品关系才真正成为数据面授权。两种模型都说明“门户里看见产品”与“请求被允许”是两件事。Azure API Management Subscription 与 Apigee API Product 给出了各自对象关系。
先冻结消费契约,再启用门户
门户启用之前,API 契约应已经通过相应 Schema 治理,网关路由也应在隔离环境可调用。Portal 不负责修复破坏性 OpenAPI 变更,更不能用一段营销文案掩盖 operation、错误模型或版本策略不清。团队需要先确定产品 owner、支持入口、目标消费者、允许的环境、身份方式、审批责任、额度口径、数据分类和退出条件。
API 文档至少包括 base URL、认证方式、operation 示例、错误语义、幂等要求、分页、速率响应 Header、版本迁移、支持渠道和凭据轮换。Try it 功能会把浏览器变成调用客户端,必须单独处理 CORS、测试凭据、可调用环境、响应脱敏和审计;生产写操作不应因 Portal 有在线调试器就默认开放。
Plan 把访问条件变成可执行对象。限流保护瞬时速率,quota 约束较长窗口的总消费,并发限制保护同时占用的资源;它们不能合并成一个“额度”。本地 Gateway 计数会随副本数变化,全局 quota 依赖共享状态或外部服务,还要明确网络分区时 fail-open 还是 fail-close。演示值只用于触发边界,生产阈值来自上游容量、消费者合同和 SLO。
在隔离环境分阶段启用
跨实现实验不要从公开生产 Catalog 开始。建立一个独立 organization、environment、tenant 或命名空间,使用虚构消费者 acme-lab、Application orders-client-lab 和两个可区分上游:orders/blue 与 profile/green。管理入口只允许回环地址、VPN 或受控 CI 身份访问,Portal 公开入口也先限制到测试网络。
实施前从目标产品实例下载管理 API 与 Portal API 规格,确认产品文档中“API、Product、Application、Subscription、Credential”的真实名称和 endpoint。跨实现只能共享能力变量,实际 URL、请求 Schema 和状态转换必须来自目标实例规格。
export MGMT_API_BASE='https://management.lab.example'
export PORTAL_BASE='https://portal.lab.example'
export GATEWAY_BASE='https://gateway.lab.example'
export LAB_CONSUMER='acme-lab'
export LAB_APPLICATION='orders-client-lab'
# 凭据由短时 Secret 注入;命令历史、CI trace 和 evidence 文件均不得记录明文。
test -n "$PORTAL_ADMIN_TOKEN"
mkdir -p evidence/portal40分阶段启用时,每一步只改变一个状态:
只建私有产品。 关联 orders API 与只读 operation,上传文档,但不发布 Catalog。证据是生产者可预览、匿名消费者不可发现、Gateway 现有路由不受影响。发布一个人工审批 Plan。 使用短窗口演示 quota 和一种明确身份方式。证据是产品可见、Plan 可申请,但未审批前没有有效 Credential。创建 Consumer 与 Application。 owner、用途、环境、回调地址和数据分类都使用虚构实验值。证据是 Application 可独立禁用,不依赖某个人保持登录。
提交并审批 Subscription。 保存 Subscription ID、状态变化、审批主体和审计事件。Credential 只进入 Secret 系统,不出现在截图、工单正文或分析事件中。再启用 Try it 与 analytics。 先限制到只读测试 API,按允许列表采集字段,并设置短保留期。证明数据路径正确后再扩大消费者范围。
Gravitee 的 Developer Portal 把发现、文档、Application、Subscription 与 Credential 放在同一消费链上,同时存在不同 Portal 实现和许可状态;这正说明 UI 菜单不能成为跨实现模型。选择任何产品时都应从目标实例 API 和当前官方文档确认启用方式,不照抄另一版本截图。
正向实验:从发现一直证明到计量
正向实验先用未登录浏览器确认产品公开元数据只包含允许字段,内部 endpoint、成员、管理 ID、未发布版本和支持工单不能泄露。登录 acme-lab 后创建 orders-client-lab,申请 Plan;审批前调用 Gateway 应被拒绝,审批后才取得 Credential。
# Header 名由目标 Plan 的身份类型决定。
curl -skD evidence/portal40/approved.headers \
-H "Authorization: Bearer $LAB_ACCESS_TOKEN" \
-H 'X-Lab-Request: portal-positive-1' \
"$GATEWAY_BASE/orders" \
-o evidence/portal40/approved.body预期正文明确返回 orders/blue,而不是 profile/green。证据包同时保存 Gateway request ID、API/Product、Application、Subscription、Plan、Credential 的不可逆指纹、配置版本、Gateway 节点、上游标识、网关状态码与上游状态码。Credential 明文不能进入日志,使用带盐哈希、末尾少量字符或产品提供的 credential ID 做关联。
随后连续调用直到越过实验 quota。成功请求数、被拒绝请求数和窗口重置必须能由 Gateway 证据与 Portal analytics 对齐;超限请求应在上游之前被拒绝,上游日志中不应出现对应 request ID。若多个 Gateway 副本下总额度随副本数线性增加,说明实际是本地计数或共享计数失效,不能把 UI 中配置的 quota 数字当成全局保证。
最后打开文档 Try it,用同一只读 operation 调用。浏览器 Network 面板应显示请求发往测试 Gateway,不应把管理 Token、生产 Credential 或 Portal Session 转发给业务上游;CORS 只允许目标 Portal origin 和必要 Header。关闭 Try it 后,普通 SDK/CLI 调用仍应正常,证明调试入口不是 API 可用性的前提。
反向实验:错误身份与错误产品必须被稳定拒绝
第一个反例把 orders-client-lab 的 Credential 用于 profile 产品。即使两个 API 由同一 Gateway 托管,也应因 Subscription/Plan 不覆盖该 API 而拒绝,上游 profile/green 不得出现请求。若成功,问题不是 Portal 页面显示,而是 Product 与 Plan 绑定、Policy scope 或消费者身份映射发生扩权。
curl -skD evidence/portal40/wrong-product.headers \
-H "Authorization: Bearer $LAB_ACCESS_TOKEN" \
-H 'X-Lab-Request: portal-negative-product' \
"$GATEWAY_BASE/profile" \
-o evidence/portal40/wrong-product.body第二个反例撤销 Credential 后立即从每个 Gateway 节点重复调用,记录 T0 到首次稳定拒绝的相对时间。撤销传播可能经过控制面、repository、缓存和数据面同步,不能承诺零延迟。测试还要覆盖旧 keep-alive 连接、新连接、控制面断网和节点重启;若某个节点继续接受旧凭据,保存节点 ID、配置版本与缓存证据,再决定是否隔离该节点。
第三个反例让 analytics backend 暂时不可达。业务请求是继续、降级还是阻断,取决于实现与配置;无论选择哪种,reporter 队列都必须有界,磁盘增长可观测,恢复后丢失与重复可量化。不能为了“分析完整”让无界队列拖垮 Gateway,也不能把 analytics 失败静默成永久数据洞。
Subscription 是状态机,不是布尔开关
Subscription 至少会经历申请、审批或拒绝、激活、暂停、恢复、撤销/关闭和到期。产品可能提供更细状态,但团队必须为每个转移定义谁能执行、数据面何时改变、是否可逆、消费者收到什么通知以及审计保留多久。
暂停适合可逆止血,撤销用于终止授权,退订表达消费者结束关系;三者不应都实现为 Portal 隐藏。Credential rotation 也不是“生成新 Key”一步:先签发新 Credential,允许受控重叠,观察新 Credential 使用率,撤销旧 Credential,再证明所有节点拒绝旧值,最后清除 Secret、日志和缓存残留。
凭据状态要独立于 Subscription 状态保存。一个 Active Subscription 可能同时有“新凭据待领取、两把凭据重叠、旧凭据待撤销、全部凭据失效”四种运行状态;反过来,Suspended Subscription 即使仍保留密钥材料,也不得继续获得授权。Azure API Management 提供主次两把 Subscription Key,适合先切换再重生成,但不替团队自动建立到期和轮换工作流;密钥还可能默认继续传给后端,需要在入口策略中删除敏感 Header 或 query。把“生成成功”当作轮换完成,会遗漏调用方切换、旧值撤销、后端日志泄漏与多节点传播。Subscription Key 管理说明明确了这些产品边界。
| 生命周期动作 | 数据面预期 | 必留证据 | 失败时的停止动作 |
|---|---|---|---|
| 签发 | 只有批准的 Application 能读取一次或写入其 Secret 目标 | credential ID、owner、scope、签发时间、到期策略 | 禁止把明文回填工单或分析系统 |
| 重叠轮换 | 新旧值在短窗口内都有效,使用率可分别观测 | 新旧指纹、调用方切换比例、窗口截止时间 | 停止扩大调用方,不提前撤销仍在使用的旧值 |
| 撤销 | 所有数据面在传播预算内稳定拒绝旧值 | 节点、配置版本、首次与持续拒绝时间、上游零命中 | 隔离未收敛节点,冻结 Product/Plan 写入 |
| 退订 | Subscription 不再授权,Portal 不再签发新凭据 | 状态转换、操作者、关联 Credential 清单 | 不删除对象以掩盖未完成撤销 |
| 删除 | 明文、Secret 副本和超期关联数据按策略清除 | 删除批次、保留例外、备份到期、反向查询 | 保持封存并升级给数据 owner |
Plan 迁移同样要保持身份类型和消费者预期。先建立新 Plan,迁移一小组 Subscription,验证额度、Policy、analytics 与计费归属,再扩大批次。直接关闭旧 Plan 可能连带关闭 Subscription,且某些实现不可逆;操作前必须根据目标产品状态机导出关系图和回退路径。
文档发布与 API 部署是两条流水线
Portal 文档可以来自 OpenAPI、AsyncAPI、Markdown 或产品自定义页面,但它们应引用同一批准契约版本。文档构建检查 operation、示例、错误码、Schema 引用和链接;Gateway 发布检查路由、Policy、Plan 与数据面配置。两条流水线在发布门禁会合,却不能互相代替。
一个常见失败是文档先显示 v2,Gateway 仍运行 v1;另一个失败是 Gateway 已切换,Portal 示例还携带旧 Header。发布证据中要同时保存文档 revision、API deployment revision、Plan revision 和 SDK/示例测试结果。若无法原子切换,先保持向后兼容窗口,再按消费者迁移状态逐步撤下旧文档和旧路由。
Portal 内容也有授权边界。公开页面只放可公开的契约和支持信息;合作方私有 API 要在服务端执行成员与 Subscription 授权,不能只靠前端隐藏菜单。Portal API、管理 API、主题插件、SSO 与动态客户端注册都属于高权限扩展面,需要独立身份、CORS、速率限制、审计、升级与许可核对。
Analytics 要能回答运营问题,也要允许删除
分析事件先服务明确问题:哪个 Product/operation 被使用、哪类 Consumer 遇到拒绝、配额是否合理、哪个版本仍有流量、上游延迟和错误由谁负责。没有用途的 Header、body、query、用户身份和 callback URL 不应因为“以后可能排障”就默认采集。
分析事件可分成三层:
| 层次 | 最小字段 | 主要用途 |
|---|---|---|
| 请求证据 | 受信 request ID、API/deployment、Gateway node、状态码、上游、延迟 | 排障与 SLO |
| 消费关系 | Product、Plan、Application、Subscription、credential ID/指纹 | 配额、采用率与撤销验证 |
| 业务归因 | 经批准的组织、成本中心、环境标签 | 运营与成本分摊 |
运营分析、计费账本和安全审计不能共用一张“万能宽表”。运营分析允许采样、聚合和迟到,回答采用率、延迟与容量;计费账本要求去重、窗口关闭和可追溯修正,不能用采样数据直接收费;安全审计记录谁在何时改变 Product、Plan、Subscription、Credential 和导出权限,保留策略通常也不同。三者可以共享稳定 ID,却应分别定义写入权威、可变字段、迟到处理、删除例外和访问角色。否则一次“清理 analytics”可能误删法定审计,一次“保留审计”又可能无限保留请求参数。
第三层最敏感,也最容易因组织改名、合并或离职而陈旧。分析系统宜使用稳定内部 ID,在受控维表中保存显示名称,并给维表与事件分别设 retention。Portal 管理员不应默认读取原始 request/response;API owner、消费者 owner、平台运维、安全审计和数据治理角色应有不同视图与导出权限。
身份维度不是天然可信。Apigee 只有在 App 关联 Product 且代理验证 API Key 或 Token 时,才能完整归因 Developer App 等维度;缺少验证时相关维度会出现 (not set)。因此分析报表里“未知消费者”激增,先检查认证策略、产品关联与字段管道,不要直接把流量归为匿名攻击。Apigee 的 Analytics 字段与归因说明和 Analytics 数据边界还表明平台可能处理开发者标识、App、Product、位置和自定义采集字段;启用 DataCapture 或导出前应按字段逐项批准,尤其不能把 Authorization、Cookie、Key、完整 query 与 body 当成默认诊断数据。
分析完整性可用不变量验证:Gateway 接受数约等于成功、上游失败和策略后拒绝之和;身份前拒绝不应被归到某个已认证 Consumer;超限请求不应到达上游;同一 request ID 不应因 reporter 重试被算成两次消费。允许的差异来自采样、异步延迟和明确的丢弃策略,必须可解释而非长期“对不上”。
容量与成本来自事件速率乘以单条大小、索引副本、保留期、查询和导出。verbose trace、完整 body 与高基数标签会同时放大网络、CPU、磁盘和隐私风险。上线前用目标流量回放测量每请求新增字节、队列峰值、索引增长和查询延迟,再决定采样、聚合、冷热分层和删除周期;不使用脱离负载的固定保留天数冒充通用答案。
成本审计至少拆成 采集量 × 单价、热存储 GB·月、冷存储 GB·月、查询扫描、跨区/跨云出口和导出副本六项,并把费用关联到 Product、Application 与环境。托管产品的保留期、可查询窗口、区域和附加包会变化,采购账本应保存当前合同值和变更日期;迁移到自建数据湖也不是免费延长保留,而是把删除、索引、查询、加密和审计责任转移给自己。费用异常的反向检查是用 Gateway 接受数推导理论事件量,再与 reporter、存储写入和账单用量逐层对账;若差异无法解释,应先停止新增高基数字段和批量导出。
数据删除要沿对象图执行
“删除 Consumer”可能只删登录主体,Application、Subscription、Credential、审计、analytics、日志、trace、导出文件、缓存与备份仍然存在。团队要维护数据资产图,为每类数据记录 controller/processor、用途、法定义务、保留策略、删除接口、备份到期和删除证明。
一次完整退订按以下顺序推进:
冻结新 Credential 与新 Subscription,通知 consumer owner,并记录撤销批次。撤销或过期全部 Credential,在每个 Gateway 节点验证旧值稳定拒绝。终止 Subscription,解除 Application 与 Product/Plan 的授权关系。
若 Application 不再承载其他 Subscription,删除 Application;再按组织关系决定是否删除 Consumer 身份。删除或不可逆匿名化 analytics、访问日志、trace、Portal 活动、导出文件和缓存中的可识别字段。对依法或安全审计必须保留的记录执行访问封存和到期删除,而不是伪装成“已经物理删除”。
等待备份自然过期或执行已批准的备份删除流程,记录尚未到期的恢复限制。
删除验收既要做正向查询,也要做反向调用:管理 API 查不到活动 Subscription 和 Credential,Portal 看不到 Application,旧 Credential 从所有节点得到拒绝,analytics 用 Application/Subscription/Consumer ID 均不能返回超出保留义务的数据,搜索索引、对象存储导出和缓存也没有孤儿副本。只收到一个 204 不能证明异步索引、备份与数据湖已完成处理。
项目接入要把产品元数据当代码审查
项目仓库保存不含 Secret 的产品描述:API 契约引用、Product/Plan ID、目标环境、审批 owner、身份类型、额度语义、文档源、数据分类、analytics 允许字段、retention policy ID 和退出 runbook。Credential 只在部署时从 Secret 系统注入,Application 不共享跨环境 Secret。
一份可审查的产品描述可以采用下面的结构。它不是任何厂商的导入格式;适配器必须根据目标实例 OpenAPI 规格把稳定字段映射到真实 API,并把返回的对象 ID 与 revision 写入部署证据。
apiVersion: platform.example/v1
kind: ApiProduct
metadata:
name: orders-partner
spec:
environment: partner-prod
apiRevision: orders-v2-approved
operations: [GET /orders/{id}]
visibility: private
plan:
identity: oauth2-client-credentials
approval: manual
rateLimit: 20rps
quota: 500000/month
analytics:
allowFields: [requestId, productId, applicationId, status, latencyMs]
retentionPolicyId: api-usage-standard
owners: [orders-api, partner-operations]
rollbackArtifact: orders-partner.previous.json这些字段不是同等风险。apiRevision 与 operations 改变授权能力面,必须先验证新旧契约兼容;visibility 改变谁能发现产品,却不自动撤销既有 Subscription;identity 改变 Credential 类型,通常不能原地回滚,需新 Plan 与新 Credential 并行迁移;approval 改变谁能获得授权;rateLimit 和 quota 改变数据面拒绝行为与共享计数容量;allowFields 和 retentionPolicyId 改变隐私、存储成本和删除义务。部署适配器遇到这些字段变化时应生成语义 diff 和审批项,而不是把整份 YAML 当普通文本覆盖。
流水线先校验 Product 引用的 API revision,再生成 Portal 文档预览;随后对 Plan 做语义 diff,检测身份类型、额度、审批、可见性和数据采集变化。部署到隔离环境后自动执行未订阅、已订阅、错误产品、超 quota、撤销旧 Credential 和 analytics 对账测试。生产发布采用小批 Consumer,达到拒绝率、延迟、计数误差或 reporter backlog 的停止阈值就回滚。
回滚时不要恢复已泄露或已撤销的 Credential。Portal 文档可回到上一 revision,Product/Plan 绑定可切回上一已验证配置,Gateway Policy 可重新部署旧制品;消费者授权则通过重新审批或签发新 Credential 恢复。这样能保留撤销审计,避免“为了回滚”让旧 Secret 复活。
故障按消费链的停止位置分型
消费者搜不到 API,先看 Product、页面、Plan 可见性与成员权限;能看到但不能申请,检查 Plan 状态、审批和 Application 约束;已审批却拿不到 Credential,检查签发任务、Secret 展示和异步队列;有 Credential 但被拒绝,检查 Gateway 配置版本、Subscription 状态、缓存与时间;请求成功但配额错误,检查计数 scope、共享 repository 与副本;请求成功但分析缺失,检查 reporter、队列、索引和字段过滤。
Portal 登录失败不能直接推断 Gateway 业务流量失败,analytics 查询失败也不能直接推断调用失败。相反,Portal 仍能登录也不能证明旧 Credential 已撤销。每层维护独立健康证据和依赖图,事故中才能决定是暂停新订阅、隔离某个 Gateway、关闭 Try it、降级 analytics,还是停止整个 Product。
机制选型从消费者关系复杂度出发
只有内部少量客户端、没有自助发现和外部消费关系时,受控配置仓库加 Secret 管理可能比完整 Portal 更简单。消费者数量增加、需要审批、Plan、Credential 自助轮换、文档分群和使用分析时,API 产品门户开始产生价值。若目标是通用服务目录、系统 owner、软件模板和 Golden Path,应使用相应开发者平台,而不是把 API 管理 Portal 扩成另一个企业首页。
自建 Portal 提供 UI 与流程自由度,却要自行承担 Portal API 授权、SSO、CORS、凭据展示、通知、搜索、可访问性、插件供应链和升级;产品内置 Portal 能减少集成,却可能受到主题、工作流、数据导出和许可证约束;托管 Portal 还能减少运行组件,但要额外验证数据驻留、身份联邦、网络边界、停服时的数据面自治和厂商退出。
选型演示不要只看 Catalog 漂亮与否。用同一组脚本测量 Product 发布、人工审批、Credential 轮换、多节点撤销、quota 一致性、analytics 对账、批量导出和删除证明。产品能力、许可包、价格、调用量、区域和保留上限会变化,应在采购时确认并纳入成本模型,不能把一次询价结果当成长期技术结论。
权限、数据、容量与成本一起治理
生产者、产品 owner、审批者、Portal 管理员、Gateway 管理员、消费者管理员、Application owner、分析只读和数据删除执行者不应共用一个超级管理员。审批者不能读取 Credential 明文,消费者管理员不能修改 Gateway Policy,分析用户不能默认导出原始 body,删除执行者的批量动作需要双人复核和审计。
管理 API、Portal API、配置导出、访问日志和 trace 都按敏感资产处理。Token 使用短期、最小 scope 和可撤销身份;自动化 identity 与人员账号分离;日志过滤 Authorization、Cookie、API Key、client secret、证书私钥和查询凭据。SSO 关闭账号后,还要回收 Application owner、组成员、离线 Token 和本地管理员后门。
容量治理同时看 Portal 峰值登录、文档静态资源、搜索索引、审批队列、Credential 签发、Gateway 计数、analytics 写入和查询。成本账至少分出平台许可或托管费用、Gateway 计算与出口、共享 repository、日志/trace/analytics 存储、通知服务、证书与身份服务、支持维护和退出迁移。月度复盘把成本归到 Product/Application,而不是只看整个平台总账。
回滚、清理与退出证明
实验清理先关闭 Try it 和 Product 可见性,阻止新申请;随后撤销 Credential、终止 Subscription、删除 Application 与虚构 Consumer;再删除实验 Product、Plan、文档 revision、索引和导出。每一步保存对象 ID 和结果,最后用旧 Credential 做一次拒绝测试,并确认两个上游都没有对应 request ID。
若使用托管实例,还要删除测试自定义域名、证书、日志 sink、对象存储导出、网络连接和付费环境;若使用 self-hosted,则停止专用 Portal/Gateway 组件,精确删除实验 namespace、数据库或索引前缀。共享存储中禁止使用全库清空和通配符删索引,所有删除都从对象清单反推。
平台退出前先导出 API/Product/Plan、Consumer/Application/Subscription 关系、Credential 元数据、文档、审计与必要 analytics,验证格式可读且不含不应迁移的 Secret。新旧平台双跑时使用新 Credential,不复制旧 Secret;逐 Consumer 比对授权、quota 和分析后切换入口。等旧平台所有 Gateway 稳定拒绝、管理身份撤销、数据按保留策略删除、账单归零,再关闭旧合同和基础设施。
一个成熟的 API 产品门户,不以页面数量或注册用户数衡量成功,而以消费关系是否可解释来衡量:谁因哪个 Subscription 获得哪项能力,凭据何时生效和失效,额度在哪里计算,分析数据如何归属,以及关系结束后哪些数据被删除、哪些因明确义务受控保留。只有这条证据链闭合,Portal 才是 API 运营系统,而不是一个更漂亮的文档站。
