ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Aptos Rust REST 客户端实战:aptos-rest-client 示例程序运行与源码解析

Aptos Rust REST 客户端实战:aptos-rest-client 示例程序运行与源码解析 Aptos Rust REST 客户端实战aptos-rest-client 示例程序运行与源码解析【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-coreaptos-rest-client是 aptos-core 仓库中封装 Aptos Full Node REST API 的 Rust SDK 客户端。本仓库在 examples 目录 中提供了一组可执行示例目前为account示例官方文档将其定位为“端到端测试”它们不接入标准cargo test流程而是要求开发者本地或远程已有一个运行中的 Aptos API 服务用真实请求验证客户端各条查询链路。读完本篇你可以直接在本地跑通该示例理解--api-url参数的解析方式、示例依次调用的每个 REST 端点以及底层Client/ClientBuilder/State/RestError的关键实现细节。一、示例的定位面向真实 API 的端到端验证crates/aptos-rest-client/examples/README.md 对示例的定位有两点关键说明这些示例实质上是REST 客户端的端到端测试Really these examples serve as end-to-end tests for the REST client它们不是标准测试不应该、也不会随标准cargo test一起运行因为执行它们的前提是已经有一个 Aptos API 在运行。从 示例入口 可以看到参数定义#[derive(Debug, Parser)] #[clap(author, version, about)] pub struct Args { /// This should include the port, e.g. http://127.0.0.1:8080 #[clap(long)] api_url: Url, }api_url是一个url::Url类型字段注释明确要求必须带上端口。这意味着 URL 必须是合法的绝对地址如http://127.0.0.1:8080传入不合法字符串时 clap 会在解析阶段直接报错退出而不是运行到一半才发现地址错误。二、运行方式一条命令打满一条查询链路从aptos-rest-client包的父目录即 crates/aptos-rest-client执行cargo run --example dir文档给出的完整示例是cargo run --example account -- --api-url http://127.0.0.1:8080其中account对应examples/account/main.rs是目录名即 example 名--api-url后面必须是指向 Full Node REST 服务的地址默认本地 Full Node 的 REST 端口为8080。运行成功后示例会以info!日志逐条打印查询结果形如Running all queries against account: 0x0000000000000000000000000000000000000000000000000000000000000001 Successfully retrieved N account resources with JSON Successfully retrieved N account resources with BCS Successfully retrieved N account modules with JSON Successfully retrieved N account modules with BCS Successfully retrieved resource 0x1::chain_id::ChainId with JSON Successfully retrieved balance ... Successfully retrieved resource 0x1::chain_id::ChainId with BCS示例入口在 main.rs L22-L31 中初始化日志、解析参数并构造客户端let args Args::parse(); let client Client::new(args.api_url); let address AccountAddress::ONE; info!(Running all queries against account: {}, address);所有查询统一打在系统账户0x1AccountAddress::ONE即框架核心代码地址上该账户天然持有ChainId资源保证查询不会落空。三、account 示例逐条调用链拆解按 main.rs L33-L100 的执行顺序示例覆盖了两类端点形态JSON 与 BCS。3.1 账户资源与模块的整页查询JSON BCS 双形态let results client.get_account_resources(address).await?; // JSON let results client.get_account_resources_bcs(address).await?; // BCS let results client.get_account_modules(address).await?; // JSON let results client.get_account_modules_bcs(address).await?; // BCS这四个方法对应GET /v1/accounts/{address}/resources与GET /v1/accounts/{address}/modules端点。注意它们的实现并非单次请求而是自动游标分页在 src/lib.rs 中get_account_resources内部调用paginate_with_cursor每页请求量由常量控制const RESOURCES_PER_CALL_PAGINATION: u64 9999; const MODULES_PER_CALL_PAGINATION: u64 1000;见 lib.rs L64-L65。分页循环会持续携带服务端返回的cursor请求下一页直到响应头中不再带游标为止paginate_with_cursor 实现。因此results.inner().len()打印的是跨页合并后的总数这也是示例日志中数字可能远超单页上限的原因。3.2 单个资源查询0x1::chain_id::ChainIdlet resource 0x1::chain_id::ChainId; client.get_account_resource(address, resource).await?; // JSON返回 OptionResource client.get_account_resource_bcs::ChainId(address, resource).await?; // BCS直接反序列化为 ChainId 类型这里体现了一条重要设计BCS 泛型方法get_account_resource_bcsT: DeserializeOwned直接把 BCS 字节解码为目标 Rust 类型lib.rs L1212-L1224而 JSON 版本返回的是OptionResource由调用方决定是否解析data字段。示例同时验证两条路径确保两种序列化格式都能正确返回ChainId资源。3.3 新旧两套余额查询接口的交叉校验示例中最有“端到端测试”味道的一段是 main.rs L77-L94let balance_from_new_api client .get_account_balance(address, 0x1::aptos_coin::AptosCoin) .await?; let balance_from_old_api client.view_apt_account_balance(address).await?; assert_eq!(balance_from_new_api.inner(), balance_from_old_api.inner());get_account_balance走的是GET /v1/accounts/{address}/balance/{asset_type}端点asset_type可以是 coin 类型或 fungible asset 元数据地址见 lib.rs L318-L335 的方法注释view_apt_account_balance走的是 view function 端点POST /v1/view内部执行0x1::coin::balanceview_account_balance_bcs_impl。两条路径语义等价示例用assert_eq!断言二者结果一致——任何一侧端点行为回归都会直接让程序 panic 失败。3.4 一个容易被忽略的细节示例自带单元测试main.rs L105-L109 在main之外还定义了一个真正的单元测试#[test] fn verify_tool() { use clap::CommandFactory; Args::command().debug_assert() }它用 clap 的debug_assert校验参数定义如--api-url长选项与字段名一致、帮助文本无冲突等。也就是说虽然示例本身不在标准测试里跑但这条 clap 参数自检仍然会随cargo test -p aptos-rest-client一起执行保证命令行接口不会在重构中悄悄损坏。四、客户端底层实现要点源码佐证示例里一行Client::new(args.api_url)背后ClientBuilder做了不少默认配置理解它们对排查真实环境问题很有帮助。4.1 默认配置版本路径、超时、请求头client_builder.rs L34-L109 中版本路径前缀默认为v1/DEFAULT_VERSION_PATH_BASE见 lib.rs L58。构造 URL 时所有端点路径都会先拼接该前缀例如accounts/0x1/resources最终变成{base}/v1/accounts/0x1/resources。若自定义base_url已带路径如https://host/v2get_version_path_with_base会优先沿用 base URL 自带的路径lib.rs L1927-L1941超时默认 10 秒timeout: Duration::from_secs(10)client_builder.rs L54可通过ClientBuilder::timeout()覆盖客户端标识头自动注入X-Aptos-Client请求头取值为aptos-rust-sdk/{crate 版本号}client_builder.rs L44-L48服务端可据此统计 SDK 流量API Key 环境变量若环境中设置了X_API_KEY会自动以Authorization: Bearer {key}形式附加到请求头client_builder.rs L58-L60。对接需要密钥的托管 API 网关时无需改代码Cookie 存储开启cookie_store(true)以适配需要会话态的 API 网关场景。4.2 每次响应的 State 元数据从 HTTP 头解析所有成功的响应都会被包装成ResponseT其中附带一个State结构state.rs L10-L21包含chain_id、epoch、ledger version、timestamp、block_height、分页cursor、encryption_key等字段。这些值全部来自服务端响应头中的X-Aptos-Chain-Id、X-Aptos-Ledger-Version、X-Aptos-Cursor等自定义头State::from_headers。这一点有两层实际意义一致性校验get_ledger_information内部会断言头解析出的 chain_id/epoch/version 与响应体字段一致lib.rs L397-L417分页闭环paginate_with_cursor依赖的游标就是从X-Aptos-Cursor头里取的cursor.clone_from(response.state().cursor)。如果服务端少返回这些头State::from_headers会直接报错而非静默继续——这是排查“分页卡死/数据缺失”时应先检查的点。4.3 错误模型与可重试判断客户端错误统一收敛到RestError枚举error.rs L146-L162区分 API 错误Api带状态码与链上状态、BCS/JSON 反序列化错误、URL 解析错误、HTTP 层错误等。对于需要重试的场景lib.rs L1943-L1957 提供retriable判定仅429 Too Many Requests、500、502、503、504、507 Insufficient Storage视为可重试另有retriable_with_404变体把 404 也纳入可重试范围。配套的try_until_ok辅助函数lib.rs L1784-L1834以指数退避初始 1s翻倍默认总等待 60s执行重试。示例程序未直接使用重试逻辑但生产代码里对全节点 API 的轮询如wait_for_transaction_by_hash本质上依赖同样的状态机思路轮询间隔 500ms并带“服务端滞后容忍窗口”默认 60sDEFAULT_MAX_SERVER_LAG_WAIT_DURATION以避免因 Full Node 同步延迟而误判交易丢失。五、适用前提与注意事项必须先有运行中的 Aptos API本地 Full Node 默认 REST 端口为8080也可指向 Devnet/Testnet 的公共 API 地址。ClientBuilder同时内置了AptosBaseUrl::Mainnet/Devnet/Testnet三个预设地址client_builder.rs L16-L32示例使用的是Custom分支即你自己传入的 URL示例不是单元测试不要在 CI 里把cargo run --example account当作无依赖测试运行它需要外部服务失败与否取决于 API 端状态依赖版本aptos-rest-client依赖aptos-api-types、aptos-types、reqwest等 workspace 依赖见 Cargo.toml L19-L34作为库引入其他工程时注意这些传递依赖日志输出示例通过aptos_logger::Logger::new().init()初始化日志debug!/info!输出会按日志级别落到终端排查连接问题时可调高日志级别观察重试与轮询细节。六、延伸阅读路径内容路径示例运行说明本文主体文档crates/aptos-rest-client/examples/README.mdaccount 示例入口crates/aptos-rest-client/examples/account/main.rs客户端核心实现Client、分页、重试crates/aptos-rest-client/src/lib.rs构建器与默认配置crates/aptos-rest-client/src/client_builder.rsState 头解析crates/aptos-rest-client/src/state.rs错误类型crates/aptos-rest-client/src/error.rs包定义与依赖crates/aptos-rest-client/Cargo.toml综上examples/account虽然只有百余行代码但恰好串起了aptos-rest-client最常用的能力面双序列化格式JSON/BCS的资源与模块查询、单资源精确读取、新旧余额接口的等价性校验以及 clap 参数自检。把它当作“可运行的接口契约”来跑一遍再对照上文的ClientBuilder默认值、State头解析与RestError模型阅读源码是理解这个 Rust SDK 最快的路径。【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表