拓冰建站拓冰建站
首页 / 资讯中心 / 正文

swagger-codegen 只读属性(readOnly)深度解析:以 HasOnlyReadOnly 模型文档与 Java/jersey1 生成样例为切入点

开发工具代码生成API设计【免费下载链接】swagger-codegenswagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.项目地址https://gitcode.com/gh_mirrors/sw/swagger-codegen点击查看免费下载本文围绕 swagger-codegen 仓库中由代码生成器自动产出的模型文档samples/client/petstore/java/jersey1/docs/HasOnlyReadOnly.md展开剖析该文档所代表的HasOnlyReadOnly模型在 OpenAPI/Swagger 规格中的定义、在生成的 Java 客户端代码中的形态以及readOnly: true这一属性修饰符从规格解析到模板渲染的完整链路。读完本文你将掌握 swagger-codegen 处理只读属性的底层机制能够在自己的项目中正确使用readOnly修饰符并理解生成代码与生成文档之间的对应关系。1. HasOnlyReadOnly 文档是什么一份自动生成的模型参考文档HasOnlyReadOnly.md位于 petstore Java 客户端jersey1 库样例的文档目录中属于 swagger-codegen 在生成客户端代码时同时生成的模型级参考文档。其内容是一张属性表完整信息如下名称类型说明NotesbarString[optional]fooString[optional]这份文档不是手写的而是由生成器模板引擎Mustache驱动产出任何 OpenAPI/Swagger 定义中的 schema在生成 Java 客户端时都会对应生成一份形如ModelName.md的文档。生成该文档的模板位于 pojo_doc.mustache其核心结构如下# {{classname}} ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- {{#vars}}**{{name}}** | ... | {{description}} | {{^required}} [optional]{{/required}}{{#readOnly}} [readonly]{{/readOnly}} {{/vars}}从模板可以看到 Notes 列的两个标记规则非必填属性required为空渲染[optional]只读属性readOnly: true渲染[readonly]。HasOnlyReadOnly的两个属性均未声明required因此 Notes 列为[optional]。值得注意的细节是当前版本模板在只读时会额外追加[readonly]标记而仓库中已提交的这份样例文档只含有[optional]可以推断该样例是由较早版本的模板生成的——若用当前代码重新生成Notes 列将变为[optional] [readonly]的形式。这也提示读者仓库samples/目录下的产物与最新模板之间存在版本差分析时应以模板与源码为准。2. 规格源头readOnly: true 的两种写法v2 / v3HasOnlyReadOnly是 petstore 测试规格petstore fake中专门用于验证只读属性处理逻辑的模型。该模型在仓库的多个规格 fixture 中均有定义且跨越 OpenAPI v2 与 v3 两种格式。OpenAPI v2Swagger 2.0定义在 petstorefake.yaml 的definitions区约第 1321 行起hasOnlyReadOnly: type: object properties: bar: type: string readOnly: true foo: type: string readOnly: truev2 中同样存在ReadOnlyFirst模型约第 1313 行起它只将bar标记为readOnly: true、baz为普通属性与hasOnlyReadOnly两个属性全部只读形成对照测试组合。OpenAPI v3 定义在 v3 规格 petstore3fake.yaml约第 1885 行起与 petstoreMixed3.yaml约第 2159 行起中模型定义位于components/schemas之下hasOnlyReadOnly: type: object properties: bar: type: string readOnly: true foo: type: string readOnly: true可以看到除容器关键字不同v2 为definitionsv3 为components/schemas外属性定义完全一致两个String类型属性bar、foo均被标记为readOnly: true且都未声明required。这正是该模型名称的由来——HasOnlyReadOnly即只有只读属性的模型其存在意义就是专门验证当模型所有属性都是只读时生成器各语言模板能否正确产出对应的 getter、省略 setter并保持文档一致。3. 生成的 Java 模型只读属性为何只有 getter、没有 setter生成的 Java 模型类位于 HasOnlyReadOnly.java。打开该类可以观察到两个关键特征特征一两个属性均以JsonProperty注解声明但没有对应的 setter。public class HasOnlyReadOnly { JsonProperty(bar) private String bar null; JsonProperty(foo) private String foo null; /** * Get bar * return bar **/ ApiModelProperty(value ) public String getBar() { return bar; } /** * Get foo * return foo **/ ApiModelProperty(value ) public String getFoo() { return foo; } // 注意没有 setBar / setFoo 方法 }特征二类中只生成了 getter、equals、hashCode、toString等通用方法。这一行为的实现依据在 Java 语言模板 pojo.mustache 中setter 的渲染被{{^isReadOnly}}条件块包裹即仅当属性非只读时才生成 setter/** * Get {{name}} * return {{name}} **/ ApiModelProperty(...) public {{{datatypeWithEnum}}} {{#isBoolean}}is{{/isBoolean}}{{getter}}() { return {{name}}; } {{^isReadOnly}} public void {{setter}}({{{datatypeWithEnum}}} {{name}}) { this.{{name}} {{name}}; } {{/isReadOnly}}语义很明确只读属性表示该字段由服务端生成或维护客户端只读不写。因此生成器为bar、foo各生成一个 getter而跳过 setter。这一点在序列化层面也保持一致Jackson 反序列化时若 JSON 响应中包含bar/foo字段仍可通过 getter 对应的字段注入读取但客户端代码在编译期就没有写入口从 API 设计上杜绝了对只读字段的误写。值得一提的是jersey1 与 jersey3 等各 Java 子库的 pojo 模板在这部分逻辑上保持一致jersey3 的 pojo.mustache 中 setter 同样受只读条件约束说明只读属性不生成 setter是 Java 生成器各 library 共同遵守的约定。4. 生成器底层isReadOnly 标志从 OpenAPI 属性到 CodegenProperty 的传递文档与代码中的只读行为最终都归结于 swagger-codegen 内部中间模型CodegenProperty的一个布尔字段。在 CodegenProperty.java 中public boolean isReadOnly false;该字段默认值为false。OpenAPI 定义中的readOnly修饰符在代码生成阶段被解析并映射到这个字段映射逻辑位于 DefaultCodegen.java约第 1723 行if (p.getReadOnly() ! null) { property.isReadOnly p.getReadOnly(); }即当规格中该属性显式声明了readOnly时就把其布尔值原样赋给CodegenProperty.isReadOnly。此后所有语言模板都可以通过{{#isReadOnly}}/{{^isReadOnly}}访问这一标志从而决定渲染策略文档模板pojo_doc.mustache依据它输出[readonly]标记Java 模型模板pojo.mustache依据它省略 setter同时equals/hashCodeCodegenProperty.java 第 103、249 行附近也将该标志纳入比较与哈希计算保证中间模型的一致性判断正确。从源码结构还可以推断isReadOnly是模板可见的公开字段各语言生成器Java、Python、Go、Swift 等都能基于它实现各自的只读语义如某些语言生成只读注解、其他语言完全省略写入方法这构成了 swagger-codegen 一处解析、处处可用的模板驱动机制的核心环节。5. 实战验证如何重新生成并核对这份文档仓库中samples/client/petstore/java/jersey1/是一份完整的生成产物目录包含源码、文档与构建文件其 README.md 说明了作为独立 Maven 工程使用与发布的方式。要自行验证只读属性 → 无 setter 文档 Notes 标记的完整链路可按照以下思路操作确认生成器可用swagger-codegen 提供命令行入口模块 swagger-codegen-cli读者可按 docs/generators.md 中介绍的方式构建并获取 CLI 可执行包mvn package后使用target下的 CLI jar或直接使用 Docker 镜像方式运行参见 Dockerfile 与 docs/docker.md。选择生成器与库本文对应的样例使用 Java 生成器-l java并指定--library jersey1子库规格文件可使用 petstorefake.yamlv2或 petstore3fake.yamlv3二者均包含hasOnlyReadOnly模型定义。核对产出生成后检查两处——源码目录下HasOnlyReadOnly.java应只有getBar()/getFoo()不应出现setBar()/setFoo()文档目录下HasOnlyReadOnly.md属性表应包含bar、foo两行Notes 列在当前模板下会同时出现[optional] [readonly]与仓库中旧版样例略有差异属模板版本演进所致。对照参照组可同时观察ReadOnlyFirstv2 规格中bar只读、baz普通的生成结果比较部分只读与全部只读两种模型在 getter/setter 数量上的差别从而加深对{{^isReadOnly}}条件渲染的理解。6. 小结通过HasOnlyReadOnly.md这一看似只有两行属性表的文档可以还原出 swagger-codegen 处理只读属性的完整技术链路规格层readOnly: true在 v2/v3 规格中写法一致仅容器位置不同definitions/components/schemas解析层DefaultCodegen将规格的readOnly值映射到CodegenProperty.isReadOnlyDefaultCodegen.java模板层pojo.mustache用{{^isReadOnly}}控制 setter 的生成pojo_doc.mustache用{{#readOnly}}控制文档 Notes 列的输出产物层生成的 Java 类HasOnlyReadOnly.java只含 getter、不含 setter与文档表述完全对应。对于在自己的 OpenAPI 定义中使用readOnly: true的开发者核心结论是该修饰符会让生成客户端只读该字段、禁止写入适合服务端生成 ID、时间戳、状态等不应由客户端修改的字段而对于 swagger-codegen 的二次开发者isReadOnly标志则是扩展自定义模板时实现只读语义的标准入口。赞分享开发工具代码生成API设计【免费下载链接】swagger-codegenswagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.项目地址https://gitcode.com/gh_mirrors/sw/swagger-codegen点击查看免费下载相关推荐swagger-codegen 生成 C 只读属性模型以 HasOnlyReadOnly 为例解读 readOnly 语义的实现swagger codegen 生成 C 只读属性模型以 HasOnlyReadOnly 为例解读 readOnly 语义的实现 导读 本文以 swagger开发工具代码生成API设计Swagger Codegen C 客户端模型文档解析以 HasOnlyReadOnly 为例理解 readOnly 属性的生成与使用Swagger Codegen C 客户端模型文档解析以 HasOnlyReadOnly 为例理解 readOnly 属性的生成与使用 导读 本文以 swag开发工具代码生成API设计深入解析 swagger-codegen 如何生成 HasOnlyReadOnly 只读模型从 OpenAPI readOnly 属性到 C 私有 Setter深入解析 swagger codegen 如何生成 HasOnlyReadOnly 只读模型从 OpenAPI readOnly 属性到 C 私有 Sette开发工具代码生成API设计创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门