☰
lakeFS Rust SDK 对象操作指南:ObjectsApi 全端点实战解析
2026/10/13 6:02:51 网站建设 项目流程
  • 数据工程
  • 数据湖
  • 大数据
  • 对象存储
  • 后端

【免费下载链接】lakeFS

lakeFS - Data version control for your data lake | Git for data

项目地址:https://gitcode.com/gh_mirrors/la/lakeFS
点击查看免费下载

导读

ObjectsApi是 lakeFS Rust 客户端(lakefs_sdk)中负责对象(Object)级数据操作的 API 集合,覆盖对象的上传、下载、复制、删除、元数据查询与修改等完整生命周期。本文以clients/rust/docs/ObjectsApi.md为核心骨架,结合clients/rust/src/apis/objects_api.rs的实现代码与服务端pkg/api/controller.go的对应逻辑,逐一剖析全部 10 个端点的函数签名、参数语义、认证与返回类型,并给出可直接运行的 Rust 调用示例。读完本文,你将能够用 Rust 实现对 lakeFS 分支对象的全链路读写与版本管理操作。

一、API 概览:方法与端点速查

ObjectsApi中所有 URI 均以/api/v1为基准(base path)。文档中列出的全部端点如下表:

Method(Rust 函数)HTTP 请求说明
copy_objectPOST /repositories/{repository}/branches/{branch}/objects/copy创建对象的副本
delete_objectDELETE /repositories/{repository}/branches/{branch}/objects删除对象,对象缺失时不会返回 NotFound 错误
delete_objectsPOST /repositories/{repository}/branches/{branch}/objects/delete批量删除对象,缺失对象不返回 NotFound 错误
get_objectGET /repositories/{repository}/refs/{ref}/objects获取对象内容
get_underlying_propertiesGET /repositories/{repository}/refs/{ref}/objects/underlyingProperties获取对象在底层存储上的属性
head_objectHEAD /repositories/{repository}/refs/{ref}/objects检查对象是否存在
list_objectsGET /repositories/{repository}/refs/{ref}/objects/ls列出指定前缀下的对象
stat_objectGET /repositories/{repository}/refs/{ref}/objects/stat获取对象元数据
update_object_user_metadataPUT /repositories/{repository}/branches/{branch}/objects/stat/user_metadata重写(全部)对象元数据
upload_objectPOST /repositories/{repository}/branches/{branch}/objects上传对象

所有端点均支持三种认证方式:basic_auth(HTTP Basic)、cookie_auth(会话 Cookie)与jwt_token(Bearer Token)。从 Rust 实现看,认证实际通过Configuration中的basic_auth与bearer_access_token字段注入请求头(见 clients/rust/src/apis/configuration.rs)。

在函数签名中,repository、branch、ref、path等路径/查询参数在实现中都会经过crate::apis::urlencode进行 URL 编码后拼接到请求行,因此仓库名、分支名中包含特殊字符时无需手动转义(见 clients/rust/src/apis/objects_api.rs)。

一个重要的语义区分:ref与branch

  • 只读端点(get_object、head_object、list_objects、stat_object、get_underlying_properties)的路径参数是ref,文档明确说明“a reference (could be either a branch or a commit ID)”,即既可以传分支名,也可以传提交 ID(Commit ID),实现对历史版本的只读访问;
  • 写端点(copy_object、delete_object、delete_objects、upload_object、update_object_user_metadata)的路径参数是branch,因为写入必须发生在可变的分支之上。

二、copy_object:创建对象的副本

pub async fn copy_object( configuration: &configuration::Configuration, repository: &str, branch: &str, // 目标分支 dest_path: &str, // 目标路径(相对分支) object_copy_creation: models::ObjectCopyCreation, // 复制参数(请求体) ) -> Result<models::ObjectStats, Error<CopyObjectError>>
  • HTTP 请求:POST /repositories/{repository}/branches/{branch}/objects/copy,dest_path以查询参数传递,请求体为 JSON。
  • Content-Type:application/json;Accept:application/json。
  • 返回类型:models::ObjectStats,即复制后新对象的统计信息。

ObjectCopyCreation 请求体结构

ObjectCopyCreation(见 clients/rust/src/models/object_copy_creation.rs)包含以下字段:

字段类型是否必填说明
src_pathString必填源对象路径(相对 ref)
src_refOption<String>可选源引用,为空时默认使用目标分支作为源 ref
forceOption<bool>可选是否强制覆盖目标路径上已存在的对象
shallowOption<bool>可选创建浅拷贝(不复制实际数据)。目前仅支持同一仓库、同一分支内的浅拷贝;浅拷贝对象可能与垃圾回收(GC)和分支保留策略产生冲突,需谨慎使用

构造请求体示例

let copy_creation = models::ObjectCopyCreation { src_path: "data/raw.parquet".to_string(), src_ref: Some("main".to_string()), force: Some(true), shallow: Some(false), }; let stats = objects_api::copy_object(&config, "my-repo", "feature-1", "data/copied.parquet", copy_creation).await?; println!("copied to: {}", stats.path);

服务端行为印证

在服务端 pkg/api/controller.go 中,CopyObject做了以下校验与处理:

  1. 权限校验:调用方必须同时拥有源路径的fs:ReadObject权限和目标路径的fs:WriteObject权限(对应 pkg/permissions/actions.go 中定义的ReadObjectAction与WriteObjectAction);
  2. 分支存在性检查:目标branch不存在时返回404 branch not found;
  3. 默认源 ref:src_ref为空时回退为branch本身(与 SDK 文档描述一致);
  4. 最终调用Catalog.CopyEntry完成复制,并将源对象的 checksum、size、content_type、物理地址等打包成ObjectStats返回。

需要说明:从 SDK 生成的代码看,copy_object的请求体是整体 JSON 序列化发送的,且src_path为必填;而shallow、force等为可选字段,序列化时会通过skip_serializing_if = "Option::is_none"自动省略空值。

三、delete_object 与 delete_objects:删除对象

3.1 单个删除 delete_object

pub async fn delete_object( configuration: &configuration::Configuration, repository: &str, branch: &str, path: &str, // 相对分支的路径 force: Option<bool>, // 默认 false no_tombstone: Option<bool>, // 默认 false,实验性 ) -> Result<(), Error<DeleteObjectError>>
  • HTTP 请求:DELETE /repositories/{repository}/branches/{branch}/objects,path、force、no_tombstone均为查询参数。
  • 返回类型:空响应体(成功时返回Ok(()))。
  • 文档特别注明:对象缺失时不会返回 NotFound 错误(删除是幂等的)。

3.2 批量删除 delete_objects

pub async fn delete_objects( configuration: &configuration::Configuration, repository: &str, branch: &str, path_list: models::PathList, // 请求体:待删除路径列表 force: Option<bool>, no_tombstone: Option<bool>, ) -> Result<models::ObjectErrorList, Error<DeleteObjectsError>>
  • HTTP 请求:POST /repositories/{repository}/branches/{branch}/objects/delete,请求体为 JSON,查询参数为force、no_tombstone。
  • Content-Type:application/json;Accept:application/json。
  • 返回类型:models::ObjectErrorList,即逐个路径的操作错误列表。

参数说明与请求体构造

  • force:类型Option<bool>,默认false。从服务端实现看,它控制删除时的强制程度(例如绕过对象的不可删除保护);传入Some(true)时才会在查询串中携带force=true(见 objects_api.rs)。
  • no_tombstone:类型Option<bool>,默认false,文档标注EXPERIMENTAL,语义为“在可能的情况下无 tombstone 删除条目”。
  • PathList(见 clients/rust/src/models/path_list.rs)只有一个字段paths: Vec<String>:
let path_list = models::PathList::new(vec![ "logs/2024/01.log".to_string(), "logs/2024/02.log".to_string(), ]); let errors = objects_api::delete_objects(&config, "my-repo", "main", path_list, Some(false), None).await?; // ObjectErrorList.errors: Vec<ObjectError>

ObjectError 结构

批量删除的返回类型ObjectErrorList由Vec<ObjectError>组成(见 clients/rust/src/models/object_error.rs):

字段类型说明
status_codei32该路径操作对应的 HTTP 状态码
messageString状态码的简短说明
pathOption<String>受影响的路径

四、get_object:下载对象内容

pub async fn get_object( configuration: &configuration::Configuration, repository: &str, r#ref: &str, // 分支名或提交 ID path: &str, // 相对 ref 的路径 range: Option<&str>, // 要获取的字节范围(Range 头) if_none_match: Option<&str>, // 仅当对象 ETag 不匹配时返回响应(If-None-Match 头) presign: Option<bool>, // 是否返回预签名 URL ) -> Result<std::path::PathBuf, Error<GetObjectError>>
  • HTTP 请求:GET /repositories/{repository}/refs/{ref}/objects,path、presign为查询参数;range通过Range请求头传递,if_none_match通过If-None-Match请求头传递(见 objects_api.rs)。
  • Accept:application/octet-stream, application/json。
  • 返回类型:std::path::PathBuf。

使用说明

  • presign:当传入Some(true)时,响应返回的是一个预签名 HTTP URL(而非内容本身);从ObjectStats模型的定义可知,预签名 URL 具有过期时间,且可能因认证 token 即将过期而被截短(见 clients/rust/src/models/object_stats.rs)。SDK 层此模式下返回的PathBuf代表下载后保存到本地文件系统的路径。
  • range:支持 HTTP Range 语义,例如Some("bytes=0-1023"),用于断点续传或只读部分数据。
  • if_none_match:用于条件请求,例如传入对象当前 ETag,可避免重复下载未变更的内容。

五、head_object:检查对象是否存在

pub async fn head_object( configuration: &configuration::Configuration, repository: &str, r#ref: &str, path: &str, range: Option<&str>, ) -> Result<(), Error<HeadObjectError>>
  • HTTP 请求:HEAD /repositories/{repository}/refs/{ref}/objects,path为查询参数,range为Range请求头。
  • 返回类型:空响应体(Ok(())表示对象存在;Err(Error::ResponseError(...))表示不存在或请求失败)。
  • 该端点是get_object的轻量版,只校验对象的存在性与元数据,不传输内容,适合作为批处理任务前的存在性检查。从 SDK 生成的错误枚举看,HeadObjectError覆盖 400/401/404/410/416/429 等状态码(objects_api.rs)。

六、get_underlying_properties:查询底层存储属性

pub async fn get_underlying_properties( configuration: &configuration::Configuration, repository: &str, r#ref: &str, path: &str, ) -> Result<models::UnderlyingObjectProperties, Error<GetUnderlyingPropertiesError>>
  • HTTP 请求:GET /repositories/{repository}/refs/{ref}/objects/underlyingProperties,path为查询参数。
  • 返回类型:models::UnderlyingObjectProperties。
  • Accept:application/json。

该端点用于查询对象在底层对象存储(S3、GS、Azure Blob 等)上的原生属性。UnderlyingObjectProperties(见 clients/rust/src/models/underlying_object_properties.rs)当前只有一个字段:

字段类型说明
storage_classOption<Option<String>>底层存储上的存储类别(双层 Option 用于区分“未返回”与“显式 null”,由serde_with::rust::double_option处理)

注意:该端点返回的是底层存储的属性,与stat_object返回的 lakeFS 元数据(ObjectStats)不同。

七、list_objects:列出前缀下的对象

pub async fn list_objects( configuration: &configuration::Configuration, repository: &str, r#ref: &str, user_metadata: Option<bool>, // 默认 true presign: Option<bool>, after: Option<&str>, // 返回此值之后的条目 amount: Option<i32>, // 返回条目数量,默认 100 delimiter: Option<&str>, // 用于按公共前缀分组的分隔符 prefix: Option<&str>, // 只返回以该值为前缀的条目 ) -> Result<models::ObjectStatsList, Error<ListObjectsError>>
  • HTTP 请求:GET /repositories/{repository}/refs/{ref}/objects/ls,全部以查询参数传递。
  • 返回类型:models::ObjectStatsList。
  • Accept:application/json。

参数语义详解

参数默认值作用
user_metadatatrue结果中是否包含用户自定义元数据(ObjectStats.metadata)
presign无结果中的physical_address是否返回预签名 HTTP URL
after无分页游标,返回该值之后的条目(配合Pagination.next_offset使用)
amount100每页返回的最大条目数
delimiter无类似 S3 ListObjects 的分隔符(如/),将公共前缀折叠为path_type = common_prefix的条目
prefix无前缀过滤,只列出以该前缀开头的对象

返回结构 ObjectStatsList

ObjectStatsList(见 clients/rust/src/models/object_stats_list.rs)包含pagination: Pagination与results: Vec<ObjectStats>。Pagination(见 clients/rust/src/models/pagination.rs)提供:

字段类型说明
has_morebool是否还有下一页
next_offsetString用于获取下一页的游标值
resultsi32本页结果数量
max_per_pagei32每页最大条目数

分页遍历示例

let mut after: Option<String> = None; loop { let page = objects_api::list_objects( &config, "my-repo", "main", Some(true), None, after.as_deref(), Some(100), Some("/"), Some("data/"), ).await?; for obj in &page.results { println!("{} ({:?})", obj.path, obj.path_type); } if !page.pagination.has_more { break; } after = Some(page.pagination.next_offset.clone()); }

关于 path_type 与 ObjectStats

ObjectStats(见 clients/rust/src/models/object_stats.rs)是对象操作中最核心的返回模型,字段包括:path、path_type(common_prefix/object)、physical_address(底层存储原生 URI,如s3://...、gs://...;presign 时则为 HTTP URL)、physical_address_expiry(预签名 URL 过期时间,Unix 秒)、checksum、size_bytes、mtime、metadata(用户自定义元数据 Map)、content_type。其中size_bytes、metadata、content_type在返回时通常都会填充,但在客户端上传等场景下允许缺省。

八、stat_object:获取对象元数据

pub async fn stat_object( configuration: &configuration::Configuration, repository: &str, r#ref: &str, path: &str, user_metadata: Option<bool>, // 默认 true presign: Option<bool>, ) -> Result<models::ObjectStats, Error<StatObjectError>>
  • HTTP 请求:GET /repositories/{repository}/refs/{ref}/objects/stat,path、user_metadata、presign为查询参数。
  • 返回类型:models::ObjectStats(结构详见上文)。
  • Accept:application/json。

典型用途

  • 读取对象大小、checksum、mtime,用于增量同步判断;
  • 携带presign=true获取可直接下载的预签名 URL 并交给其他工具消费;
  • 结合head_object实现“先 stat 再决定是否下载”的缓存策略。

九、update_object_user_metadata:重写对象元数据

pub async fn update_object_user_metadata( configuration: &configuration::Configuration, repository: &str, branch: &str, // 要更新的分支 path: &str, // 相对分支的对象路径 update_object_user_metadata: models::UpdateObjectUserMetadata, // 请求体 ) -> Result<(), Error<UpdateObjectUserMetadataError>>
  • HTTP 请求:PUT /repositories/{repository}/branches/{branch}/objects/stat/user_metadata,path为查询参数,请求体为 JSON。
  • Content-Type:application/json;Accept:application/json。
  • 返回类型:空响应体。
  • 语义为rewrite (all) object metadata:即整体重写对象的用户元数据,而非增量合并。

UpdateObjectUserMetadata(见 clients/rust/src/models/update_object_user_metadata.rs)只有一个字段set: HashMap<String, String>,表示要设置的完整元数据键值集合:

let mut metadata = std::collections::HashMap::new(); metadata.insert("owner".to_string(), "data-team".to_string()); metadata.insert("stage".to_string(), "prod".to_string()); let req = models::UpdateObjectUserMetadata::new(metadata); objects_api::update_object_user_metadata(&config, "my-repo", "main", "data/raw.parquet", req).await?;

由于是“整体重写”,调用前应先用stat_object获取现有元数据,再在内存中合并修改后整体提交,避免丢失已有键值。

十、upload_object:上传对象

pub async fn upload_object( configuration: &configuration::Configuration, repository: &str, branch: &str, path: &str, // 相对分支的路径 if_none_match: Option<&str>, // "*":仅在路径尚不存在时允许上传 if_match: Option<&str>, // 对象的 ETag:仅当当前 ETag 匹配时允许操作 storage_class: Option<&str>, // 已弃用,未来版本不再支持 force: Option<bool>, // 默认 false content: Option<std::path::PathBuf>, // 单文件上传,必须命名为 "content" ) -> Result<models::ObjectStats, Error<UploadObjectError>>
  • HTTP 请求:POST /repositories/{repository}/branches/{branch}/objects,path、storageClass、force为查询参数;if_none_match通过If-None-Match请求头、if_match通过If-Match请求头传递。
  • Content-Type:multipart/form-data或application/octet-stream;Accept:application/json。
  • 返回类型:models::ObjectStats(上传完成后对象的统计信息)。

参数语义与注意事项

参数说明
if_none_match设为"*"可实现原子性“仅当该路径尚无对象时才允许上传”(即 create-if-absent);其他值不支持。服务端在 pkg/api/controller.go 中对该值做了专门处理:若路径已存在则返回412 Precondition Failed,并将条件封装为 graveler 的WithCondition参与写入
if_match设为对象当前 ETag,可实现 compare-and-set 式原子更新,防止并发覆盖
storage_class文档明确标注Deprecated,未来版本将移除该能力
force默认false,用于控制是否强制覆盖已有对象
content单文件上传,multipart 表单中的文件字段必须命名为"content"

服务端双通道实现

服务端UploadObject(pkg/api/controller.go)根据Content-Type走两条路径:

  1. application/octet-stream(非 multipart):直接把请求体作为对象内容写入底层存储(upload.WriteBlob),适合流式上传;
  2. multipart/form-data:解析 multipart 中的content字段,逐段读取并上传。

同时服务端会先校验调用方对目标路径是否拥有fs:WriteObject权限、仓库与分支是否存在(分支不存在直接返回404 branch not found,避免在错误分支上白白上传大文件)。

注意:当前 SDK 生成的upload_object对content参数只创建了空 multipart form,代码中留有// TODO: support file upload for 'content' parameter(见 objects_api.rs)。因此在当前生成版本中,若需要携带文件内容上传,可改用application/octet-stream方式直传(自行构造请求),或关注该 TODO 的后续实现。

十一、错误处理与认证配置

类型化错误枚举

objects_api.rs为每个端点定义了对应的类型化错误枚举(如CopyObjectError、UploadObjectError、GetObjectError等),每个枚举通过#[serde(untagged)]反序列化服务端返回的 JSON 错误体,并覆盖该端点可能的 HTTP 状态码。例如:

  • GetObjectError:400 / 401 / 404 / 410 / 416 / 429(410 Gone 与 416 Range Not Satisfiable 常见于对象过期与非法 Range);
  • UploadObjectError:400 / 401 / 403 / 404 / 412 / 429 / 501(412 对应If-None-Match: *冲突;501 对应未支持的能力,如已弃用的 storage class 相关操作);
  • 所有端点均包含429 Too Many Requests(限流)与DefaultResponse(未预期错误)。

调用时通过Error<XxxError>的ResponseError变体即可拿到status、content与反序列化后的错误实体:

match objects_api::stat_object(&config, "my-repo", "main", "nope.txt", Some(true), None).await { Ok(stats) => println!("{} bytes", stats.size_bytes.unwrap_or(0)), Err(e) => match e { apis::Error::ResponseError(resp) => { eprintln!("HTTP {}: {}", resp.status, resp.content); } _ => eprintln!("transport error: {:?}", e), }, }

配置与认证

所有端点共享同一个Configuration(clients/rust/src/apis/configuration.rs),默认base_path为/api/v1。在真实部署中应将其替换为完整的 lakeFS 服务地址,例如http://localhost:8000/api/v1,并配置认证:

let config = apis::configuration::Configuration { base_path: "http://localhost:8000/api/v1".to_owned(), basic_auth: Some(( "AKIAIOSFODNN7EXAMPLE".to_owned(), Some("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY".to_owned()), )), ..Default::default() };

lakeFS 的访问密钥对(Access Key / Secret Key)即对应 HTTP Basic 认证的用户名/密码;若使用 Bearer Token(如jwt_token),则设置bearer_access_token字段。每次调用传入&config即可,reqwest::Client在内部复用连接。

十二、对象操作的最佳实践小结

综合文档与源码,用ObjectsApi构建对象工作流时有几点值得注意:

  1. 读写分离的 ref 语义:查询/下载一律走ref(分支名或 Commit ID),实现“读历史版本”;写入走branch,保证数据只落在可变的当前分支上。
  2. 原子写保护:需要“不存在才创建”时用upload_object(if_none_match=Some("*"));需要“防并发覆盖”时用if_match=Some(etag)(配合stat_object先取 ETag)。
  3. 分页与前缀:list_objects用prefix过滤 +after/Pagination.next_offset游标翻页,delimiter可模拟目录层级(common_prefix)。
  4. 预签名访问:get_object、stat_object、list_objects都支持presign=true,可将底层对象存储的访问以临时 URL 形式安全地交给第三方消费。
  5. 幂等删除:delete_object/delete_objects对缺失对象不报错,适合在清理任务中直接使用;批量删除返回ObjectErrorList,可针对每个路径的错误单独处理。
  6. 元数据整体重写:update_object_user_metadata是“全量替换”语义,修改前先stat_object拉取现值,避免误丢键值。

以上即为ObjectsApi的完整端点图谱与实战要点。进一步可参考 SDK 目录下的模型文档(如 ObjectStats、ObjectCopyCreation)以及服务端实现 pkg/api/controller.go,以便在需要时深入定制行为。

  • 数据工程
  • 数据湖
  • 大数据
  • 对象存储
  • 后端

【免费下载链接】lakeFS

lakeFS - Data version control for your data lake | Git for data

项目地址:https://gitcode.com/gh_mirrors/la/lakeFS
点击查看免费下载

相关推荐

上一篇:如何快速掌握Maxun工作流引擎:Where-What条件配对机制详解
下一篇:sam2_hiera_base_plus.fb_r896_2pt1与Transformers集成指南:轻松实现图像特征提取

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询