napp-macro 1.0.1

NASA application entry attribute
Documentation

napp-macro

#[nasa::application(...)] 属性宏的实现 crate。业务项目不直接依赖它,经 nasa 门面的 application feature 使用;运行时语义见 napp 与 运维指南。

宏把业务的异步 main 改写为统一进程入口:

  • 生成静态 ApplicationSpec(组件声明顺序、编译期缺省应用名)并调用 napp::run,真实 main 返回 std::process::ExitCode。
  • 声明 "web" 时在 crate 根自动生成 mvc_router!(nasa::Application) 收集端,并把业务 crate 内 nominal 的路由项投影为运行时稳定的 RouteMeta;业务不得再手写 mvc_router!(会因 crate::__mvc 重复定义编译失败)。
  • 业务 main 变成启动 Hook:零参数或接收一个 Application,返回 anyhow::Result<()>;成功返回后资源封存,运行由 Runner 接管。

编译期校验(与运行期同口径,先在宏上失败):

  • 组件白名单:log、nacos-config、telemetry、db、redis、cache、saga、kafka、 outbox、auth、web、ws、nacos-discovery、scheduling;未知或重复组件拒绝。
  • 业务可按任意顺序书写;宏固定规范为 log -> nacos-config -> telemetry -> db -> redis -> cache -> saga -> kafka -> outbox -> auth -> web -> ws -> nacos-discovery -> scheduling。
  • saga 隐式加入 DB 与 Outbox;独立 outbox 隐式加入 DB。Inbox 是事务内原语,没有组件字符串; Kafka 或其它 transport 不由 Saga 推断。
  • 隐式依赖只补齐缺项;显式同时声明 saga、db、outbox 与只声明 saga 生成同一组件图。
  • 组合约束:auth 必须和 web 同时声明;其余依赖关系由运行期根据最终配置继续校验。
  • 每个声明组件都会生成 feature 探测常量引用,能力未启用时在业务 crate 编译阶段直接失败。
  • 入口契约:必须是 crate 根的 async fn main,非泛型、至多一个 Application 参数、返回 anyhow::Result<()>;生成的类型门禁同时要求 Hook future 为 Send + 'static。入口不能再叠加 #[tokio::main] 或 #[EnableScheduling] / #[EnableAsync],因为 Application 已拥有 runtime 与调度 生命周期。
  • 生成 crate 根锚点模块:属性放错位置时错误直接指向宏调用处。

宏内路径解析复用 macro-support(直接依赖优先、门面回退、Cargo 重命名兼容)。

使用示例

[dependencies]
nasa = { version = "1", features = ["application", "log", "redis", "cache", "web"] }
#[nasa::application("web", "cache", "redis", "log")]
async fn main(_app: nasa::Application) -> anyhow::Result<()> {
    Ok(())
}

虽然源码按 web, cache, redis, log 书写,生成的规范启动顺序仍是 log -> redis -> cache -> web。

YML 配置与边界

本宏不读取 yml;它只生成 ApplicationSpec。zcf/application.yml 和各组件配置由 napp 运行时读取。

  • 属性只能放在 crate 根异步 main 上。
  • 声明 "web" 后宏会生成唯一的路由收集模块,业务不能再手工生成同名收集器。
  • Hook 返回成功后资源登记入口封口,运行期不能继续修改组件图。
  • feature 缺失、重复组件、未知组件和非法组合都在编译期拒绝。