概述
在后端和前端共同开发时,消除重复编写相同 API 合同和类型的瓶颈,将路由器·处理程序·MongoDB 字段字符串等重复开发工作转变为基于源的生成.
起源故事
我同时处理后端和前端。在创建一个功能时,我在 Java WebFlux 中编写端点和请求/响应 DTO,然后在前端再次编写相同的 URL 和 TypeScript 类型。为了直接匹配 Swagger 文档,我不得不将后端中已存在的信息以另一种格式再次转移。
最大的瓶颈是将后端创建的 API 合同重新编写为前端可以使用的形式。如果 URL、HTTP 方法、路径/查询参数或请求/响应结构中的任何一个在两边被不同地修改,我会在编译后才发现问题。这不仅仅是麻烦,而是同样的内容由人管理两次所产生的不一致性是更大的问题。
我也想减少创建 RouterFunction 和处理程序时的重复。如果在路由器中添加了 ApiAccountHandler::search 这样的引用,那么即使是不存在的处理程序类和方法骨架也应该自动生成。在编写 MongoDB 查询时,像 "username" 这样的字符串重复使用实体字段名称也很麻烦且容易出错,因此我在同一工具中添加了读取实体源并生成 Java 枚举的功能。
因此,Swagger/OpenAPI 生成、处理程序骨架生成和 Mongo 实体字段枚举生成首先完成,随后在使用 RSocket 时也添加了 AsyncAPI 生成。虽然看起来是各自独立的想法,但出发点是相同的。让机器代替人类编写已经在后端源中记录的事实,开发工具可以生成可供机器读取的部分。
开发哲学
以后端源为基准
RouterFunction、处理程序、DTO 和实体中已有的信息用作 API 文档和生成代码的原始数据。关键是不要在单独的文件中重新管理相同的合同。
选择开发时自动化而非运行时魔法
不是拦截生产请求的框架,而是在本地开发环境中分析源并生成实际文件。可以目视检查结果并进行版本控制。
遵循可预测的项目惯例
不以理解所有 Java 代码为目标。优先分析我实际使用的 WebFlux 功能端点结构的明确规则。
消除重复的连接区间
在后端端点生成 Swagger,前端生成器读取该文档以创建服务和类型,形成一个自动化链。
后端读取内容
RouterFunction 源
读取HTTP方法、嵌套路径、处理程序方法引用和谓词。
处理程序源
读取请求体、查询/路径值和响应发布者类型。
请求/响应 DTO
将后端已编写的Java类型连接到OpenAPI模式。
Mongo实体源
读取Java字段和@Field的存储原始名称,@Document集合。
RSocket控制器
读取@MessageMapping路由和请求/响应有效负载类型。
创造而非重复编写
swagger.json
将REST端点创建为前端服务和TypeScript类型生成器可以使用的API契约。
asyncapi-rsocket.json
将RSocket路由和有效负载创建为前端RSocket客户端生成器可以读取的契约。
处理程序源
根据在RouterFunction中首先写的处理程序引用生成和修正类和方法骨架。
{Entity}Fields枚举
将字符串字段名称转换为枚举,以避免重复实体的Java字段和存储原始名称。
CollectionNames枚举
生成可在@Document中声明的集合名称以替代字符串使用。
当前项目的自动化流程
• 在后端编写RouterFunction、处理程序和Java请求/响应DTO。
• 本地配置文件的观察者检测源更改并更新swagger.json或asyncapi-rsocket.json。
• 前端的@byeolnaerim/typed-rx-http生成脚本读取文档并生成服务函数和TypeScript类型。
• 在屏幕代码中,不需要重新编写URL和响应类型,而是导入生成的函数进行使用。
• 当实体更改时,查询中使用的字段枚举和集合枚举也会一起更新。