背景
不知道你是否也有过这样的习惯,当我们在阅读一个产品的开放 API 文档时,会不自觉地从其可读性与规范性来判断该团队技术的专业程度。因为从本质上看,API 定义与团队的工程规范以及数据库表结构息息相关,高质量的 API 定义,往往意味着背后有良好的数据模型与领域设计。反之,则容易暴露出系统结构上的混乱。
那么如何定义高质量的 API 接口?估计你会立马会想到 RESTful API(Representational State Transfer),RESTful API 是目前最流行的接口设计风格,它通过对资源的抽象来定义系统的数据结构与行为,在 RESTful API 中,每个资源都有一个唯一的 URL,而 HTTP 方法(如 GET、POST、PUT 和 DELETE)则用于定义对该资源的操作。
RESTful API 的设计规范好像已经非常清晰,这样看似乎我们已经掌握了 API 接口定义的方法论,但实际落地中你会发现,在面对复杂业务场景时,依然会遇到拿不准接口路径该如何定义、字段如何命名的尴尬。有的场景很适合 RESTful,有的却模棱两可,还有的完全无法用 RESTful 的方式优雅表达。
本篇文章将通过一个典型的接口定义场景,带你掌握 API 接口定义的方法,理解这套方法后,你将能在面对各种接口定义难题时游刃有余、从容决策。
数据导入接口定义场景
需求背景
假设你接到一个新需求:需要开发一个接口数据导入接口。目标是将外部或历史系统的接口定义(API 接口规范、接口列表、接口文档、Schema 等) 导入到当前平台中。该导入接口应具备以下能力:
- 支持多种类型的数据导入:例如 OpenAPI(Swagger)、GraphQL Schema、gRPC/Protobuf、RPC 描述或自定义接口清单;
- 可配置导入选项:字段映射、示例数据策略、路径处理方式、校验规则等;
- 版本与命名冲突处理:支持覆盖、新版本创建、自动合并、冲突提示等机制。
竞品调研
拿到以上的需求后,如果你不是一位非常资深的开发,第一步不要立刻按照自己的习惯去设计接口,而是先研究行业内成熟工具的做法。尤其推荐优先参考海外优秀竞品,它们在标准化和工程实践上往往更成熟。
Postman
在调研 Postman 竞品的开放接口中,我们看到了导入接口 /import/openapi?workspace={{workspaceId}} 的定义,相关链接:Postman API 导入:
这里我们可以学习几点:
- 路径命名采用
import,很语义化,是一个重要参考; - 请求体采用清晰的分层结构:
{
"type": "{{APIspecificationType}}",
"input": "{{APIspecification}}",
"options": {
"{{optionName}}": "{{optionvalue}}"
}
}
input支持多种数据类型(文件、URL、直接文本、JSON/YAML);options导入选项较为丰富,如:
"options": {
"folderStrategy": "Path",
"disableOptionalParameters": true,
"exampleParametersResolution": "Schema"
}
- 提供
byTags的导入方式,参考 get-elements-by-tag。
Stoplight
Stoplight 没有看到提供导入开放 API,但其导出 API 有值得借鉴之处,导出接口链接为:Stoplight API 导出。
我们能收获到接口路径的命名和字段规范:
- 路径规范:
/projects/{project_id}/branches/{branch_name},说明其操作资源均明确归属于某个项目/分支; - 字段命名使用下划线风格:如
include_internal; - 提到 Stable IDs 的概念概念:确保文档或 API 内容在移动、重命名或变更后,其对外发布的 URL 不会改变,从而避免链接失效。
ReadyAPI
ReadyAPI 虽未提供导入 API,但从其文档 Working With Postman、Exporting APIs 中可参考:
- 支持 OAS 版本选择、认证方式、进阶导入选项:
OAS version、credentials、advanced options; - 对不同 API 定义类型(Definition Types)可抽象为
protocol。
RapidAPI
RapidAPI 是 GraphQL 平台 API,没有看到相关导入的接口,不过在其他文档介绍中收获到支持 scope 控制,可以导入完整 API 或仅选择部分 API,实现更精细的资源范围选择方式:
README
README 有导入相关接口:上传 API 规范,参数命名更倾向使用 spec,而非 data。
设计过程和思路
有了以上竞品参考后,这时我们就可以针对我们的需求进行接口定义了。
接口路径设计
导入的资源属于某个项目,因此路径可设计为:
POST /projects/{project_id}/import
表达资源的归属关系。
请求结构设计
建议采用分层结构,清晰、可扩展:
{
"type": "OpenAPI",
"input": { ... },
"options": { ... }
}
输入类型
input 可支持多种数据类型:URL、内嵌 JSON/YAML。
导入选项
结合以上竞品经验,导入选项定义如下:
-
结构转换选项:
folderStrategy(文件夹结构映射方式);exampleParametersResolution(示例参数解析策略)。
-
数据约束选项:
disableOptionalParameters(忽略可选参数);include_internal(是否包含内部资源)。
-
范围控制(scope):
- 部分导入、跳过某些 tag/route。
-
冲突处理机制(非常关键):
-
限流与错误处理:
- 应提供
rateLimited错误说明,返回详细的校验报告,指导用户如何处理限流。
- 应提供
-
Stable ID 支持:
- 引入
stable_id概念,避免导入过程中资源 ID 改变造成链接失效。
- 引入
其他优质 API 参考
在设计整个接口体系时,可以持续参考下面这些成熟产品的 API 规范:
总结
通过本篇文章,相信你已经掌握了从需求分析、竞品调研、API 设计 的完整方法。以后面对各种复杂的接口定义场景,你将能够设计出结构合理、语义清晰、扩展性强的 API,再也不用担心自家产品的开放 API 被别人吐槽。如果你觉得有更好的方法或者有什么地方遗漏、疑惑,欢迎评论讨论。