在当今敏捷软件领域,构建健壮且可扩展的应用程序依赖于定义良好的 API。API 设计优先方法提供了一种结构化方法,即在编写任何代码之前精心设计 API 契约。该策略由用于同步 API 的 OpenAPI 规范和用于异步 API 的 AsyncAPI 规范提供支持。
本文(一篇有观点的教程)为在同步.NET API 项目中实现 API 设计优先提供了实用指南,重点关注其在开发、测试和无缝集成到DevOps CI/CD 管道中的优势。稍后将跟进一篇关于 AsyncAPI 的文章。
理解 API 设计优先原则
API 设计优先原则意味着在深入实施代码之前,使用像 OpenAPI 规范这样的契约语言优先设计和规范 API 接口。这种方法已有十多年的历史,但许多组织仍采用代码优先方法。有许多关于此的文章,简要介绍以奠定基础:
- 增强团队协作:API 契约作为蓝图,确保构建两端的团队在某一点相遇。
- 加速开发:前端和客户端团队可以基于 OAS 使用模拟服务器开始工作,甚至在后端实现完成之前。
- 提高 API 可用性:提前精心设计可导致更直观、一致且易于使用的 API。
- 自动化就绪:OAS 充当机器可读的蓝图,实现开发生命周期各个阶段的自动化。
OpenAPI 规范(OAS)的核心作用
- OpenAPI 规范(OAS)是 API 设计优先工作流的基石。它提供了一种标准化格式(YAML 或 JSON)来描述 RESTful API,详细说明了从端点和操作到请求和响应模式、身份验证等各个方面。可以将 OAS 视为 API 的权威蓝图。作者个人倾向于 YAML,因为它在代码库中更适用(合并嵌套 JSON 文件有时会很棘手)。
在.NET 中利用 API 设计优先方法进行设计和开发
- 设计:Swagger 编辑器或 VS Code 的 OpenAPI 插件是定义 OAS 的优秀工具。Open API 倡议是权威指南。主要发布版本 2 和 3 之间存在细微差异。越来越多的工具支持版本 3 发布。
开发:
服务器:使用 NSwag 或 openapi-generator 生成.NET 接口和 DTO。作者更喜欢
openapi-generator-cli
,基于个人舒适度和广泛的社区支持。这些接口和 DTO 可以在生态系统中实现。一般来说,.Net 生态系统支持基于模板的平台 - 这些 DTO 和接口可以导入到使用这些模板生成的解决方案中。如果不行,使用 openapi-generator 生成的项目和解决方案定义。- 前提条件:npm 和 Java jdk 11 或更高版本
- 安装
openapi-generator-cli - npm
安装-g @openapitools/openapi-generator-cli
- 通过
openapi-generator-cli
验证 OAS - 创建
openapi-generator-cli
输入模板,因为它有助于实验和可重用性 - 使用
openapi-generator-cli
生成包含接口和 DTO 的解决方案框架 - 更新
Program.cs
或Startup.cs
以提供生成的 Swagger。这确保了代码生成的 Swagger 保证了正在实施的内容。 - 在
Program.cs
或Startup.cs
中创建静态文件托管能力,并确保在 Swagger UI 中也提供此功能。SwaggerUI 中静态 OAS 的可用性是需求,而 SwaggerUI 中生成的 OAS 是已构建内容的证明。
-.NET 生态系统中的代码生成器在与构建插件的集成方面不如 Java 生态系统流畅,但 DTO 和带有所有格式化程序和验证器的控制器框架非常有用。
客户端:客户端生成生态系统相对更成熟,有 nuget 包和其他 cli 实用程序。为了在本文中保持一致性,作者将坚持使用
openapi-generator-cli
。- 前提条件:OAS 文件、npm 和 Java jdk 11 或更高版本
- 安装
openapi-generator-cli
(如果尚未安装) - 通过
openapi-generator-cli
验证 OAS(如果尚未验证) - 创建生成器配置文件
- 使用
openapi-generator-cli
生成客户端 - 将生成的代码添加到客户端项目:
- (可选)自定义生成的客户端
CLI 示例:
Shell
# install openapi-generator-cli refer to https://openapi-generator.tech/docs/installation
npm install -g @openapitools/openapi-generator-cli
# install validation openapi-generator-cli
openapi-generator-cli version
#validate OAS refer to https://openapi-generator.tech/docs/usage#validate
openapi-generator-cli validate -i <OASfile>
YAML
# input yaml sample for generator
# csharp as generator name for client and aspnetcore for server
# openapi-generator-cli version
# refer to https://openapi-generator.tech/docs/usage#configuration-file
generatorName: csharp
inputSpec:./path/to/your/openapi.yaml # Path to your OpenAPI specification file
outputDir:./GeneratedCode # Output directory for the generated code
additionalProperties:
OperationIsAsunc: "true"
packageName: "your meaningful namespace"
Shell
# Server Generator rwer tohttps://openapi-generator.tech/docs/usage#generate
# My preference is using input file and batch operation https://openapi-generator.tech/docs/usage#batch
openapi-generator-cli batch <input file>
在 API 设计优先方法中测试客户端和服务器
服务器端测试:
- 规划和初始阶段:利用初始 OAS 定义来规划各种测试方面,包括单元、集成等,根据应用程序团队的需求。
- 使用.NET 库进行单元测试:在测试框架(xUnit、NUnit、MSTest)中使用.NET 库,如 NJsonSchema.Validation 和断言库(如 FluentAssertions),根据 OAS 模式验证 API 响应,确保.NET API 契约的履行。
- 模拟和隔离:在测试中,利用.NET 模拟库(如 WireMock.Net)或内存测试服务器(Microsoft.AspNetCore.Mvc.Testing),配置 OAS 规范,以隔离.NET API 并模拟依赖服务行为。
- 部署和验证:OAS 对于验证和管理部署的.NET API 至关重要;创建自动化.NET 集成测试,在部署后运行以验证实时 API 端点对 OAS 规范的遵守。
- API 网关集成:对于由 Azure API Management 管理的面向互联网的 API,OAS 作为结构定义,使 APIM 能够实施策略并生成开发人员门户文档。
客户端测试:
- 生成的客户端集成:在客户端应用程序的测试项目(例如单独的 xUnit、NUnit 或 MSTest 项目)中添加项目引用或包含生成的客户端代码文件。
- 客户端实例化:在测试类中创建生成的 API 客户端类的实例,可能为其提供指向模拟服务器或受控测试环境的 HttpClient 实例,用于测试目的。
- 模拟进行单元测试:使用模拟库(如 Moq)创建 HttpClient 或 IHttpClientFactory 的模拟实现,以隔离测试客户端逻辑,模拟不同的 API 响应,而无需实际的网络调用。
- 模拟响应配置:设置模拟 HttpClient 以返回表示预期 API 端点响应(包括成功和错误场景)的特定 HttpResponseMessage 实例,遵循 OAS 中的定义,包括状态码、头和内容。
- 客户端方法调用:调用生成的 API 客户端上与要测试的 API 端点对应的方法。
- 成功响应断言:对于返回数据的 API 调用,断言客户端将 JSON 响应正确反序列化为生成的 C#模型类,根据 OAS 期望验证属性和值。
- 错误处理断言:测试生成的客户端对 OAS 中记录的不同 HTTP 错误状态码的处理,断言预期的异常抛出(如果配置)或适当的错误模型实例返回。
- 请求参数验证(使用模拟):验证生成的客户端正确构建 HTTP 请求,包括方法、URL、头和内容(基于 OAS 的请求体序列化)。
- 集成测试(测试环境):对于集成测试,将生成的客户端指向专用测试环境中的运行服务器实例,以验证客户端与实际 API 实现之间的端到端交互。
将 OpenAPI 规范集成到 Azure DevOps CI/CD 管道中
构建管道:
- OAS 验证:验证 OAS 文件模式。
- OAS 清理:清理 OAS 文件以符合风格和最佳实践。
- 代码生成(可选 - 条件):生成.NET 服务器存根(如果需要)。
- 客户端 SDK 生成:生成.NET 客户端 SDK 并打包为 NuGet 工件。
- 构建.NET 应用程序:编译你的.NET 微服务。
- 运行单元和集成测试:根据 OAS 和其他逻辑验证实现。
- 容器镜像生成:为微服务构建 Docker 镜像。
- 生成 Helm 图表配置:创建用于 Kubernetes 部署的 Helm 图表文件。
- 工件发布:发布编译的应用程序、Docker 镜像、Helm 图表、生成的代码和客户端 SDK 作为构建工件。
发布管道:
- 部署到 Kubernetes:使用环境特定的配置将 Docker 镜像和 Helm 图表部署到目标 Rancher Kubernetes 集群。
- 验证部署健康:检查 Kubernetes 就绪和存活探针或执行基本的 API 健康检查。
- 部署后契约验证:对部署的 API 运行自动化.NET 集成测试,以确保遵守 OAS。
- Azure API Management 更新:使用构建工件中的 OAS 文件在 Azure API Management 中导入/更新 API 定义。
- (可选)应用 API 策略(APIM):在 Azure API Management 中配置或更新 API 策略。
未来趋势
预计.NET 工具将继续发展,以进一步简化 API 设计优先工作流,包括更集成的代码生成能力和增强的对契约测试和 API 治理的支持。以下是 2025 年.NET 生态系统中流行框架的比较研究:
特征 | NSwag | Swashbuckle | openapi-generator | Kiota |
---|---|---|---|---|
主要功能 | 规范生成 & 客户端/服务器代码生成 | 规范生成 & API UI | 客户端/服务器代码生成 | 客户端代码生成 |
客户端代码生成 | 是(C#、TypeScript - Angular、React、jQuery 等) | 否(依赖外部工具) | 是(广泛的语言支持,包括 C#/.NET) | 是(C#、TypeScript、Java、Go、Python、PHP、Ruby、CLI) |
服务器代码生成 | 是(C# ASP.NET Core / Web API 控制器) | 否 | 是(服务器存根,适用于 ASP.NET Core 和许多其他框架/语言) | 否 |
从代码生成规范 | 是(适用于 ASP.NET / ASP.NET Core) | 是(主要用于 ASP.NET Core 的功能) | 否 | 否 |
社区支持 | 活跃(GitHub),在.NET 社区中根深蒂固 | 非常大(历史标准),由于.NET 9 的变化面临潜在下降 | 非常大(多语言),活跃的开源,已知有许多开放问题 | 正在增长(微软支持),开源,积极开发 |
开发者采用 | 在.NET 中很高,经常与 Swashbuckle 一起使用或作为替代方案 | 在 ASP.NET Core 中非常高(通常是默认的),未来的采用可能会减少 | 在各种语言中中等到高;对于跨平台客户端生成很受欢迎 | 正在增长,特别是对于 Microsoft Graph 和现代.NET 项目 |
构建管道 / NuGet 支持 | 优秀(MSBuild 包、CLI 工具、.NET 工具、CodeGen NuGets) | 优秀(核心 NuGet 包用于运行时,CLI 工具用于规范提取) | 良好(主要通过 CLI - JAR/npm/Docker,需要脚本进行构建集成) | 优秀(.NET 全局工具用于生成,核心库 NuGets 用于客户端) |
生态系统重点 | 强大的.NET & TypeScript | 强大的 ASP.NET Core | 语言无关 | 多语言,具有强大的.NET 集成模式 |
易用性(.NET) | 良好,多种集成选项,包括 GUI | 非常好(简单的设置,用于规范/UI) | 中等(CLI 使用,可能存在配置复杂性) | 良好(现代.NET 工具集成) |
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。