搜索/为模块化网络服务添加模块,并守住模块边界

为模块化网络服务添加模块,并守住模块边界

让AI修改或扩展由模块组成的网络服务时使用。模块之间只通过共享接口连接,用仓库自带的构建方式和测试,返回可以安全展示给客户端的错误,并且不在请求之间共享状态。

要使用这个AI规则
## 模块之间通过共享接口连接,不调用彼此的内部实现 - 将模块系统视为扩展功能的核心边界。认证、存储、验证、转换、路由和协议端点应实现共享框架接口,而不是通过彼此的内部实现细节直接调用。 - 将稳定接口、配置原语、地址处理、错误类型和日志契约放在可复用的框架层中。具体实现应放在按角色划分的内部包中。 - 保持可执行程序的入口点精简。它应加载服务包,确保内置模块已注册,并调用启动序列。 - 通过配置和延迟初始化注册表连接顶层模块。根据匹配规则选择验证器、修改器和目标端,并通过由这些组件组成的显式管线处理每个请求或消息。 - 让实现依赖稳定接口,而不是依赖同级实现,以避免循环依赖。 ## 用仓库的构建包装器构建,并运行受影响的测试 - 将仓库的构建包装器作为规范构建路径,包括它支持的构建标签或功能选项。不得用遗漏版本元数据或必要标志的临时编译器命令取代它。 - 对横跨多个部分的变更运行完整的单元测试套件。当行为跨越协议、存储或投递边界时,应从文档指定的工作目录运行集成测试工具。 - 保留构建系统执行的版本信息注入。如果运行环境使用依赖原生实现的组件,应在诊断源代码之前确认所需的原生编译器和库可用。 - 迭代期间优先运行针对特定包的测试,然后在完成前运行直接受影响的集成路径。报告所有跳过的测试及其具体环境原因。 ## 把新模块放进对应角色的目录并注册 1. 将实现放在与其角色对应的内部目录中,例如验证、目标端、认证、存储、查询、转换或端点处理目录。 2. 同时实现通用模块生命周期接口和角色专用接口。将角色契约保留在稳定的框架层中。 3. 使用既定的角色前缀命名约定,在包初始化期间注册工厂。 4. 通过仓库指定的注册导入项或清单,将实现加入服务的内置模块连接配置。如果既定模式要求注册仅通过副作用完成,则注册代码必须保持仅产生该副作用。 5. 如果已有角色骨架或辅助工具,应以其为起点。只有当模块确实不保留跨请求的可变状态时,才使用无状态辅助工具。 6. 添加聚焦于配置、注册、成功行为、临时故障和边界错误映射的测试。 ## 返回标明能否重试、不向客户端暴露内部信息的错误 - 对跨越模块边界的错误使用框架的结构化错误包。当调用方需要协议状态、重试行为或模块归属信息时,不得返回未分类的格式化错误。 - 包含外部状态码、受支持时的增强状态或子类型、对客户端安全的通用消息,以及负责处理的检查项或目标端名称。 - 明确标记瞬时故障,使调度器能够区分可重试条件和永久拒绝。 - 面向客户端的消息不得包含服务器配置、内部路径、凭据或实现细节。 - 为意外的内部故障附加结构化诊断字段,并通过框架日志记录器记录。保留原始原因,但不得向远程客户端暴露。 ## 不在请求之间共享状态,并在后台任务中恢复panic - 绝不在请求或消息之间共享每个请求的可变状态。除非框架契约明确规定串行执行,否则应假定检查和转换会并发运行。 - 启动的任何goroutine或后台任务都必须在其边界恢复panic、记录故障,并防止某个任务导致整个服务崩溃。 - 在比较或存储外部标识符之前对其进行规范化。对于类似域名的标识符,应应用框架要求的Unicode表示、规范化形式和大小写折叠,而不是自行设计局部清理规则。 - 通过共享配置映射和生命周期方法解析模块配置。按照与现有模块一致的方式拒绝未知或无效设置。 - 使用框架日志记录器,而不是编程语言的全局日志记录器。如果框架提供相应功能,应创建操作范围或投递范围的日志记录器,使相关事件保留上下文。 - 合并前,在能够证明各项行为的最窄边界上,通过测试验证注册、配置解析、并发执行、规范化、结构化故障和日志记录。