Scalar SDK Generator 完整指南:从 OpenAPI 文档生成多语言类型安全 SDK
2026/9/14 11:22:17 网站建设 项目流程

Scalar SDK Generator 完整指南:从 OpenAPI 文档生成多语言类型安全 SDK

【免费下载链接】scalarScalar is an open-source API platform: 🌐 Modern REST API Client 📖 Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar

本文以 Scalar 官方 SDK Generator 文档为核心,系统讲解如何从团队既有的 OpenAPI 3.0/3.1 文档生成 TypeScript、Python、Go 等十余种语言的类型安全客户端库:覆盖目标语言与包注册表矩阵、"生成而非模板"的方法命名策略、重试/分页/流式/Webhook 等运行时能力、基于三方合并的自定义代码保留机制、通过 Pull Request 发布的版本管理模型,以及让编码 Agent 正确调用你的 API 的配套设计。读完后你将清楚 Scalar SDK Generator 的完整工作流、配置对象结构,以及如何把已有 Stainless 配置平滑迁移过来。

定位:OpenAPI-first 的 SDK 生成器

Scalar SDK Generator 的核心价值主张是:生成符合各语言习惯的类型安全客户端库,且代码生成在你自己的仓库中完成。你选择目标语言,几分钟内即可在预览仓库中审阅真实代码,再通过你自己控制的 Pull Request 从你自己的仓库发布包。

文档给出的典型生成产物长这样——同一个timeOff.listAssignments操作,在三种目标语言中的调用形态:

// TypeScript (index.ts) import WarpAPI from "warp-hr"; const client = new WarpAPI({ apiKey: process.env["API_KEY"], // defaults to the API_KEY env var }); const assignments = await client.timeOff.listAssignments();
# Python (main.py) import os from warp import Warp client = Warp( api_key=os.environ.get("WARP_API_KEY"), ) time_off = client.time_off.list_assignments()
// Go (main.go) package main import ( "context" "os" sdk "github.com/TeamWarp/warp-go-sdk" "github.com/TeamWarp/warp-go-sdk/option" ) func main() { client := sdk.NewClient( option.WithAPIKey(os.Getenv("WARP_API_KEY")), ) timeOff, err := client.TimeOff.ListAssignments(context.Background(), sdk.TimeOffListAssignmentsParams{}) if err != nil { panic(err) } _ = timeOff }

三个细节值得注意:客户端以你的 API 命名并作为默认导出,import 读起来就像产品名;凭据默认来自约定俗成的环境变量,happy path 下不需要显式传入 secret;Go 版本遵循该语言的显式 error 处理惯例。每个目标语言都按其自身惯例编写,而不是从一个共享形状模板展开——这就是"Idiomatic per language"。

文档列出的八大核心特性:

  • OpenAPI-first:从团队已维护的 OpenAPI 3.0 或 3.1 文档生成,Swagger 2.0 文档在加载时自动升级;
  • 各语言习惯化:每个目标按该语言惯例编写,而非共享模板填充;
  • 自定义代码存活:直接编辑生成文件,每次重建通过三方合并(three-way merge)把改动带下去;
  • 内建认证:API Key、Basic、Bearer、OAuth 2.0、OIDC,全部从描述文件的 security schemes 接线;
  • 通过 Pull Request 发布:版本、changelog、release 都以可审阅的 PR 形式落在你自己的仓库;
  • CLI 目标:与 SDK 并发生成完整命令行客户端,带类型化 flag 和结构化输出;
  • 流式与上传:SSE、NDJSON、WebSocket、multipart 文件上传;
  • 为编码 Agent 就绪:每个 SDK 附带 Agent Skill 和生成式参考文档。

关于开源仓库与托管服务的边界:当前仓库(Scalar 开源 monorepo)中,documentation/guides/sdks/下的这一整套文档描述了 SDK Generator 产品本身;而 SDK 生成服务是 Scalar 的托管产品,生成发生在 dashboard 侧。开源仓库中包含的是 OpenAPI 工具链相关的包(如packages/openapi-parser/packages/oas-utils/packages/snippetz/packages/themes/等),它们服务于 API 参考渲染与 OpenAPI 文档生态,可作为理解 Scalar OpenAPI 技术栈的入口。

目标语言与包注册表矩阵

每个目标都发布到其生态预期的注册表,工作流被直接生成进你的仓库。完整矩阵如下:

正式发布(Generally available)

目标包注册表
TypeScriptnpm
PythonPyPI
GoGo modules
CLInpm 与 Homebrew

实验性(Experimental)

目标包注册表
JavaMaven Central
KotlinMaven Central
RubyRubyGems
C#NuGet
PHPPackagist
Rustcrates.io
SwiftSwift Package Manager
Dartpub.dev
C++无标准注册表

正式发布的目标带有端到端测试:在每次变更时执行生成、构建,并对真实服务器运行。实验性目标生成可用的代码,其中 Java、Kotlin、Ruby、C# 位于同一套 CI 测试矩阵中——FAQ 部分进一步说明,这几者是最接近正式发布状态的,而 PHP、Rust、Swift、Dart、C++ 已能生成可用代码,但官方建议在依赖它们之前先与 Scalar 团队沟通。

生成,而非模板填充

模板式生成器机械地把每个 operation 映射成方法:结果能编译,但没人愿意对着它写代码——资源名词在每次调用中出现两遍,可选参数按位置传入,响应埋在 transport 对象后面。

模板式生成器产出:

import { Configuration, TimeOffApi } from "./generated"; const config = new Configuration({ basePath: "https://api.warp.dev", apiKey: process.env.WARP_API_KEY, }); const api = new TimeOffApi(config); const response = await api.timeOffListAssignmentsGet( undefined, // limit undefined, // cursor undefined, // options ); const assignments = response.data;

Scalar 的产出:

import WarpAPI from "warp-hr"; const client = new WarpAPI({ apiKey: process.env["API_KEY"], // defaults to the API_KEY env var }); const assignments = await client.timeOff.listAssignments();

文档指出两点完成大部分工作:客户端以 API 命名并作为默认导出,import 即产品名;凭据来自约定环境变量,happy path 无需传 secret。第三点是方法命名——Scalar 剥掉冗余的资源名词并归一化动词,使得同一组方法出现在每个资源上:

operationId模板式生成器Scalar
listPetsclient.pets.listPets()client.pet.list()
getPetByIdclient.pets.getPetById()client.pet.retrieve()
addPetclient.pets.addPet()client.pet.create()

在大型 API 上,这种一致性是"猜方法名"与"知道方法名"的区别。如需与其他生成器的完整对比,可参阅 Scalar vs Fern、Scalar vs Speakeasy 和 Scalar vs Stainless。

手写 SDK 具备的一切能力

类型

  • 每个 operation 都有类型化的请求与响应模型,从 schemas 生成;
  • oneOfanyOfallOf降低为真正的联合类型,支持 discriminator;
  • 类型化错误,暴露状态码、headers、解析后的响应体与请求元数据;
  • 按 operation 枚举的文档化错误状态码,失败处理不靠猜;
  • 零运行时依赖(除非启用需要依赖的特性)——文档举例,生成的 Warp 包"dependencies": {}为空。

网络

  • 自动分页迭代器,覆盖十种分页方案:cursor、cursor id、cursor URL、offset、page number、Linkheader、header token、body link、复合 cursor、hasMore
  • 流式响应:SSE 与 NDJSON,保留事件元数据;
  • WebSocket:Node 与浏览器分别有独立 adapter;
  • AsyncAPI 通道(实验性):降低为类型化的 connect 与 streaming 方法,收发事件按事件类型区分;
  • 文件上传:multipart、URL-encoded 或原始二进制;
  • 多内容类型 operation获得内容类型选择器,而非靠猜。

可靠性

  • 临时故障重试:默认两次尝试,覆盖网络错误、408、409、429 与 5xx 响应;
  • 服务端发送Retry-After时遵守之,否则使用可配置退避;
  • 超时默认 60 秒,可按请求覆盖;
  • 幂等键:按请求使用你 API 期望的 header;
  • 原始响应访问:可读取底层响应自行解析;
  • 自定义 HTTP 客户端注入:接入你自己的 transport、中间件或埋点。

这些默认值(超时、重试次数)不是写死的,而是由 SDK 配置对象中的clientSettings驱动,例如:

{ "clientSettings": { "defaultTimeout": 30000, "defaultRetries": { "maxRetries": 2, "initialDelaySeconds": 1, "maxDelaySeconds": 10 } } }

认证

  • API Key:header、query 参数或 cookie;
  • HTTP Basic 与 Bearer,Basic 拆分为独立的 username 与 password 选项;
  • 描述文件中声明的OAuth 2.0 与 OIDC方案;
  • 每个凭据都有环境变量默认值,quickstart 无需内联 secret;
  • 异步凭据 provider:token 需要你自行获取或刷新时使用;
  • 来自webhooks与 operationcallbacks类型化 Webhook 事件,带 HMAC-SHA256 签名校验、多密钥轮换与时间戳容差。

认证接线同样由配置对象描述。在clientSettings.opts中,每个选项可声明readEnv(环境变量名)、securityScheme(映射到 OpenAPI security scheme)与role,并可发送进 header、query、body 或 path 参数:

{ "clientSettings": { "opts": { "apiKey": { "type": "string", "description": "API key for Acme.", "readEnv": "ACME_API_KEY", "securityScheme": "apiKey", "role": "value" } }, "defaultHeaders": { "X-Acme-SDK": "true" }, "defaultEnvPrefix": "ACME" } }

文档与 Agent

  • Agent Skill:写入SKILL.md.claude/skills/,让编码 Agent 发现如何调用你的 API;
  • 生成的api.md:按资源分组列出每个方法,请求与响应类型链接到源码;
  • 注入 OpenAPI 的代码示例:作为x-codeSamples渲染在你的 API 参考中,手工整理的示例会被保留;
  • 生成的 README:认证、客户端选项、请求选项表格从描述文件自动填充;
  • 在有异步对应形态的语言中提供异步版本,暴露相同的资源树。

发布

  • 由 release-please 在你指定分支上管理版本与 changelog Pull Request
  • 面向十一个注册表的发布工作流生成进你的仓库,actions 按 commit SHA 固定;
  • 注册表支持时启用可信发布(Trusted publishing),无需长期 token;
  • 描述 SDK 表面实际变更的约定式提交(Conventional Commit)信息,破坏性变更会被标注;
  • 冒烟测试:调用每个 operation 对 mock 服务器运行并汇报结果。

完整工作流:六步走通

第 1 步:从你的 OpenAPI 文档开始

把 API 文档放入 Registry,或在创建 SDK 时直接导入。支持 OpenAPI 3.0 与 3.1,Swagger 2.0 文档在加载时升级;AsyncAPI 文档实验性可用(见 AsyncAPI 文档),每个通道变成一个 WebSocket connect 方法或 HTTP streaming 方法。

具体操作路径(见 Getting Started):登录 dashboard 后点击 "Create new SDK",若 registry 中还没有文档可直接从弹窗导入,然后选择目标语言并点 Continue,Scalar 立即开始生成。

第 2 步:选择目标

可以选一个目标,也可以一次选十几个。生成立即开始,每个目标拥有独立的配置、版本历史与构建日志。

第 3 步:先读代码,再承诺任何东西

每个目标都会自动开一个预览仓库。在接入自己的仓库之前,你可以先浏览生成代码、api.md参考与 README。

第 4 步:链接你自己的仓库

连接 SDK 应存放的仓库。Scalar 通过 GitHub App 安装授权提交,从不使用个人 token。每次构建把生成产物推送到scalar-generated分支,在scalar-next上与你自己的定制代码合并,并针对你指定的分支保持一个开放的 release Pull Request。

第 5 步:从你的仓库发布

release-please 从你的提交历史计算 release PR 的版本并维护 changelog。合并后,仓库中的工作流切 tag、创建 GitHub Release 并发布包。包名、注册表账号、发布历史都留在你手里。详见 发布总览。

生成的发布机制是一组可以逐行阅读的文件:

文件触发条件作用
.github/workflows/sdk-ci.ymlpushpull_request安装依赖并构建 SDK,确保每个变更被检查
.github/workflows/release-please.yml推送到默认分支release PR 合并时切 tag、更新 changelog、创建 GitHub Release,并从内联publishjob 发布,再把 release 同步回scalar-next
.github/workflows/release-title-edit.ymlpull_request运行 "Release PR version" 检查,把被编辑的 release PR 标题转化为Release-Ascommit
.github/workflows/sdk-release.ymlworkflow_dispatch手动重新发布已有 tag(仅当目标在 release 时发布才生成)
release-please-config.json.release-please-manifest.jsonrelease-please 的配置与版本状态,manifest 初始化后归仓库所有
VERSIONING.md记录分支模型与版本选择方式

认证方面,默认在注册表支持时使用 OIDC 可信发布:publish job 在发布时换取短期 GitHub 身份 token,无需创建、存储或轮换任何 token;不支持 OIDC 的注册表(RubyGems、需要 GPG 签名的 Maven Central)改用仓库 secrets。版本由 release-please 从提交历史按 Conventional Commits 计算;若想指定精确版本,直接编辑 release PR 标题(如release: 1.0.0),等 "Release PR version" 检查变绿再合并。

第 6 步:让它跟随你的 API

每个 SDK 可以指向你 API 文档的精确版本,也可以指向^1.2.0这样的 semver 范围。当匹配的文档发生变更时,Scalar 铸造新的 SDK 版本并重建,一次提交即可更新所有目标。

配置对象:驱动生成的单一事实来源

上述流程背后的控制面是一个统一的配置对象,描述 SDK 名称、版本、目标输出、环境、资源树、客户端设置、分页、序列化与发布行为。最小配置示例:

{ "name": "Acme API", "environments": { "production": "https://api.acme.com" }, "environmentOrder": ["production"], "targets": { "typescript": { "packageName": "@acme/api" }, "python": { "packageName": "acme_api", "projectName": "acme-api" }, "cli": { "binaryName": "acme" } }, "resources": {} }

必填属性:

属性说明
name用于生成元数据与客户端的人类可读 SDK/产品名
resources定义生成客户端与资源形状的资源树
targets每语言的打包、发布与 emitter 选项
environments生成的客户端可切换的命名 base URL
environmentOrder环境插入顺序,第一项即默认环境

targets下每个键对应一个产物,支持的键包括typescriptpythoncligorustjavakotlinswiftrubyphpcsharpcppdart;把某目标的skip设为true可保留其配置但不生成它。resources定义公共客户端树,每个资源可包含生成方法、公共模型、嵌套资源、默认请求选项与按目标的可见性规则;用skip全局或按目标省略某个方法/模型/资源,用only限制到目标列表。

分页方案在pagination中定义为可复用条目,再由方法通过paginated引用,支持类型有cursorcursorIdcursorUrloffsetpageNumber

{ "pagination": [ { "name": "cursor", "type": "cursor", "request": { "cursor": { "type": "cursor", "param": "cursor", "location": "query" } }, "response": { "items": { "type": "items", "location": "body", "path": ["data"] }, "next": { "type": "cursor", "location": "body", "path": ["next_cursor"] } } } ] }

序列化行为由querySettingsmultipartSettings控制:数组格式支持commarepeatindicesbrackets,嵌套 query 格式支持bracketsdots。此外还有openapi覆盖块(如codeSampleLanguagessecuritySchemes)、customCasingsignoredEndpointserrorsstreamingsettings等选项。完整的字段说明在 配置文档,各语言的publish等专属选项见 configuration 子目录。

自定义代码在重新生成中存活

生成的 SDK 很少覆盖所有需求:你可能会加一个便捷方法、调整一个类型、写个 helper 或改进 README。Scalar 的设计是不让你在"定制"与"保持最新"之间做选择。

直接把生成文件当普通代码编辑。每次构建执行一次三方合并:比较上一次生成、本次生成、你仓库的当前状态,然后把组合结果放进一个 PR。未改动的文件干净更新,你的编辑随行,你自己新增的文件保持原样。

对想显式保留的代码,标记一个区域:

// scalar-sdk-generator:custom-code retry-helper:start export const withBackoff = async <T>(fn: () => Promise<T>) => { // Anything in here is carried forward on every regeneration. }; // scalar-sdk-generator:custom-code retry-helper:end

冲突只会发生在重新生成的文件修改了你编辑过的同一行时。此时构建把冲突以 Pull Request 形式呈现,你在 GitHub 上像处理任何合并冲突一样解决。整个流程跑在可自检验证的受管分支上:

  • scalar-generated:纯净的生成器输出,永远不要直接提交到这里
  • scalar-next:生成输出与你的提交合并后的结果,你的定制提交应进入这个分支(直接推或走针对它的 PR);
  • scalar-merge-conflict:承载需要人工处理的冲突。

冲突也可以在 dashboard 的 conflicts 视图中逐文件选择"生成版本"或"你的版本"来解决(详见 Custom Code)。官方建议:能独立成文件就独立成文件——新文件在自己的路径上永远不会冲突,优先新增 helper 文件而非在生成文件深处编辑。

为编码 Agent 而生

Agent 正在编写越来越多调用你 API 的代码,而它们也是最容易发明出不存在方法名的消费者。每个生成的 SDK 都附带防止这种情况所需的上下文:

  • 位于SKILL.mdAgent Skill,外加.claude/skills/<name>/SKILL.md用于自动发现,内容覆盖安装、客户端构造、认证,以及如何查找调用签名;
  • 生成的api.md:列出每个 operation 及其请求与响应类型,设计上可直接放入 Agent 的上下文;
  • openapi.augmented.json:把你的描述文件与生成的代码示例、安装元数据放在一起。

三者默认全部开启。

以"会发布的 SDK"为基准的测试

SDK 生成器的价值取决于其产物能存活什么,因此这里的工程重心是测试而非模板:

  • 与已发布 SDK 的对齐(parity):测试框架把生成产物与公司在生产环境实际发布的客户端库对比,对比维度包括公共 API 形状与真实 wire traffic——在固定的 commit 上克隆生产 SDK,从双方提取公共表面,在 operation 覆盖度、wire 形状、联合类型、枚举、分页行为、必填性、参数位置上出现漂移即失败;然后驱动两个客户端对录制 mock 跑完所有共享 operation,diff 它们发出的请求;
  • 每目标冒烟测试:生成的测试框架对 mock 服务器调用每个 operation,汇报哪些失败。

从 Stainless 迁移

Stainless 正在关停其托管 SDK 生成器。Scalar 直接读取你现有的stainless.yml:资源、方法名、分页方案、各语言包名都会带过去,你的用户已经写好的调用点继续可用。实际步骤见 Stainless 迁移指南,产品对比见 Scalar vs Stainless。

定价结构

每个方案都包含一个 SDK 目标,价格随 SDK 规模(以 OpenAPI 文档中的 endpoint 数衡量)递增:Pro 上每个额外目标 $150/月,Business 上每个额外目标 $600/月。

FreeProBusinessEnterprise
包含的 SDK 目标数111定制
包含的 SDK 规模最多 25 个 endpoint100 个 endpoint250 个 endpoint定制
额外目标-每个 $150/月每个 $600/月,量大从优量大从优
试用期内所有目标免费包含包含包含包含
SSO/SAML--包含包含
RBAC、优先支持、专属 Slack/Teams 支持---包含

目标在你保存版本并排队构建时才开始计费,草稿永不计费。完整方案对比见 定价页。

常见问题

哪些目标是生产就绪的?TypeScript、Python、Go 与 CLI 目标为正式发布;其余在 dashboard 中标记为实验性。Java、Kotlin、Ruby、C# 位于与正式发布目标相同的 CI 矩阵中,是最接近的;PHP、Rust、Swift、Dart、C++ 能生成可用代码,但建议先沟通再依赖。

我拥有生成的代码吗?是。SDK 在你的仓库中、用你的包名、发布到你的注册表账号。Scalar 只对它开 Pull Request,从不代表你切 tag 或发 release。

我手写的代码会怎样?会保留。每次构建都对新生成物与你仓库的当前状态做三方合并,你的编辑存活;被标记的 custom-code 区域显式保留,你自己新增的文件绝不被触碰;冲突以 Pull Request 形式到达,由你在 GitHub 上解决。

SDK 可以发布到哪里?npm、PyPI、Go modules、Maven Central、RubyGems、NuGet、Packagist、crates.io、Swift Package Manager、pub.dev,CLI 目标还有 Homebrew。发布从生成进你仓库的工作流运行,actions 按 commit SHA 固定,注册表支持时启用可信发布。

支持哪些认证方案?header/query/cookie 中的 API Key、HTTP Basic、Bearer token,以及描述文件中声明的 OAuth 2.0 与 OIDC 方案。每个凭据有环境变量默认值,也可提供异步 provider 自行获取或刷新 token。

我的 OpenAPI 文档需要完美吗?不需要。Scalar 从你现有的文档生成起步配置,覆盖命名、分页与认证;之后你在配置编辑器中精化,而不是重写描述文件。

SDK 如何与 API 保持同步?每个 SDK 按精确版本或 semver 范围跟随其 API 文档。匹配文档变更时,Scalar 铸造新的 SDK 版本、重建所有目标并开 Pull Request——对 API 的一次提交会更新所有客户端。

下一步

  • 按 Getting Started 从 dashboard 生成第一个目标;
  • 用 Managing 构建、版本化并下载 SDK;
  • 按 Publishing 链接 GitHub 仓库并发布到注册表(发布是选择性开启的,默认关闭,合并 release 前不会发布任何东西);
  • 阅读每次构建对你 API 描述报告的 Diagnostics——每个构建都会分析 OpenAPI 文档与配置,汇报生成时不得不停止、猜测或降级的地方,并可用diagnostics.failOn(取值off/info/warn/error,默认error)、maxWarnings与按规则的rules覆盖来控制哪些发现会令构建失败;
  • 已有 Stainless 配置的话,直接迁移,资源与方法名的连续性会保留。

【免费下载链接】scalarScalar is an open-source API platform: 🌐 Modern REST API Client 📖 Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询