Objects, Versions, Streams, And Multipart Uploads

What this page gives you: a tutorial for every operation in this area, with Rust examples for each operation.
Objects are the durable source facts in Anvil. A write stores bytes, metadata, checksums, preconditions, and watch cursors. A read returns a specific object version. This tutorial covers the full object lifecycle: ordinary writes and reads, listings, versions, copy and compose operations, JSON patching, manifest compare-and-swap, append streams, and multipart uploads for large payloads.

Workflow

1.
Connect a client with an endpoint and token.
2.
Send a request that names the bucket, object, index, group, resource, or artefact explicitly.
3.
Preserve the returned version, cursor, generation, certificate, or diagnostic id when the response includes one.
4.
Use that returned value for preconditions, watch resume, catch-up, or repair verification.

Write an object

Operation: ObjectService.PutObject
Writes object bytes and metadata as a new durable object version.
{
  "operation": "PutObject",
  "rust": "use anvil_storage::{AnvilClient, proto::PutObjectRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().put_object(PutObjectRequest { bucket_name: \"documents\".into(), object_key: \"projects/acme/contract.pdf\".into(), body: \"bytes\".into(), metadata: \"metadata\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Read an object

Operation: ObjectService.GetObject
Reads object metadata and body bytes for a selected version.
{
  "operation": "GetObject",
  "rust": "use anvil_storage::{AnvilClient, proto::GetObjectRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().get_object(GetObjectRequest { bucket_name: \"documents\".into(), object_key: \"projects/acme/contract.pdf\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Read object metadata

Operation: ObjectService.HeadObject
Reads object metadata without streaming the body.
{
  "operation": "HeadObject",
  "rust": "use anvil_storage::{AnvilClient, proto::HeadObjectRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().head_object(HeadObjectRequest { bucket_name: \"documents\".into(), object_key: \"projects/acme/contract.pdf\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

List objects

Operation: ObjectService.ListObjects
Lists objects by prefix and authorisation scope.
{
  "operation": "ListObjects",
  "rust": "use anvil_storage::{AnvilClient, proto::ListObjectsRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().list_objects(ListObjectsRequest { bucket_name: \"documents\".into(), prefix: \"projects/acme/\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

List object versions

Operation: ObjectService.ListObjectVersions
Lists previous object states for audit, recovery, or explicit version reads.
{
  "operation": "ListObjectVersions",
  "rust": "use anvil_storage::{AnvilClient, proto::ListObjectVersionsRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().list_object_versions(ListObjectVersionsRequest { bucket_name: \"documents\".into(), object_key: \"projects/acme/contract.pdf\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Copy an object

Operation: ObjectService.CopyObject
Copies one object version to another key without the client re-uploading bytes.
{
  "operation": "CopyObject",
  "rust": "use anvil_storage::{AnvilClient, proto::CopyObjectRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().copy_object(CopyObjectRequest { source_bucket: \"documents\".into(), source_key: \"a.txt\".into(), target_bucket: \"documents\".into(), target_key: \"b.txt\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Compose an object

Operation: ObjectService.ComposeObject
Creates one object from ordered source object ranges or parts.
{
  "operation": "ComposeObject",
  "rust": "use anvil_storage::{AnvilClient, proto::ComposeObjectRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().compose_object(ComposeObjectRequest { bucket_name: \"documents\".into(), target_key: \"combined.bin\".into(), sources: \"sources\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Patch a JSON object

Operation: ObjectService.PatchJsonObject
Applies a structured JSON patch with preconditions.
{
  "operation": "PatchJsonObject",
  "rust": "use anvil_storage::{AnvilClient, proto::PatchJsonObjectRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().patch_json_object(PatchJsonObjectRequest { bucket_name: \"documents\".into(), object_key: \"record.json\".into(), patch: \"patch\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Compare and swap a manifest

Operation: ObjectService.CompareAndSwapManifest
Updates a manifest only when its current version matches the expected value.
{
  "operation": "CompareAndSwapManifest",
  "rust": "use anvil_storage::{AnvilClient, proto::CompareAndSwapManifestRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().compare_and_swap_manifest(CompareAndSwapManifestRequest { bucket_name: \"documents\".into(), object_key: \"manifest.json\".into(), expected_version: \"v7\".into(), manifest: \"manifest\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Watch a prefix

Operation: ObjectService.WatchPrefix
Streams object mutations below a bucket/key prefix.
{
  "operation": "WatchPrefix",
  "rust": "use anvil_storage::{AnvilClient, proto::WatchPrefixRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().watch_prefix(WatchPrefixRequest { bucket_name: \"documents\".into(), prefix: \"projects/acme/\".into(), after_cursor: \"lastCursor\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Create an append stream

Operation: ObjectService.CreateAppendStream
Creates an ordered append stream for records that should become sealed segments.
{
  "operation": "CreateAppendStream",
  "rust": "use anvil_storage::{AnvilClient, proto::CreateAppendStreamRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().create_append_stream(CreateAppendStreamRequest { bucket_name: \"events\".into(), stream_name: \"audit\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Append a stream record

Operation: ObjectService.AppendStreamRecord
Appends one record to an active stream.
{
  "operation": "AppendStreamRecord",
  "rust": "use anvil_storage::{AnvilClient, proto::AppendStreamRecordRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().append_stream_record(AppendStreamRecordRequest { bucket_name: \"events\".into(), stream_name: \"audit\".into(), record: \"record\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Seal an append stream segment

Operation: ObjectService.SealAppendStreamSegment
Closes the active segment and makes it durable for readers and derived systems.
{
  "operation": "SealAppendStreamSegment",
  "rust": "use anvil_storage::{AnvilClient, proto::SealAppendStreamSegmentRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().seal_append_stream_segment(SealAppendStreamSegmentRequest { bucket_name: \"events\".into(), stream_name: \"audit\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Initiate multipart upload

Operation: ObjectService.InitiateMultipartUpload
Starts a large-object upload split into numbered parts.
{
  "operation": "InitiateMultipartUpload",
  "rust": "use anvil_storage::{AnvilClient, proto::InitiateMultipartUploadRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().initiate_multipart_upload(InitiateMultipartUploadRequest { bucket_name: \"media\".into(), object_key: \"video.mov\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Upload multipart part

Operation: ObjectService.UploadPart
Uploads one numbered part of a multipart object.
{
  "operation": "UploadPart",
  "rust": "use anvil_storage::{AnvilClient, proto::UploadPartRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().upload_part(UploadPartRequest { upload_id: \"uploadId\".into(), part_number: \"1\".into(), body: \"bytes\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Complete multipart upload

Operation: ObjectService.CompleteMultipartUpload
Assembles uploaded parts into the final object version.
{
  "operation": "CompleteMultipartUpload",
  "rust": "use anvil_storage::{AnvilClient, proto::CompleteMultipartUploadRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().complete_multipart_upload(CompleteMultipartUploadRequest { upload_id: \"uploadId\".into(), parts: \"parts\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Abort multipart upload

Operation: ObjectService.AbortMultipartUpload
Cancels an incomplete multipart upload and releases temporary state.
{
  "operation": "AbortMultipartUpload",
  "rust": "use anvil_storage::{AnvilClient, proto::AbortMultipartUploadRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().abort_multipart_upload(AbortMultipartUploadRequest { upload_id: \"uploadId\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

Delete an object

Operation: ObjectService.DeleteObject
Writes a delete marker or removes the current object state according to policy.
{
  "operation": "DeleteObject",
  "rust": "use anvil_storage::{AnvilClient, proto::DeleteObjectRequest};\n\nlet anvil = AnvilClient::connect_with_bearer(endpoint, token).await?;\nlet response = anvil.objects().delete_object(DeleteObjectRequest { bucket_name: \"documents\".into(), object_key: \"projects/acme/contract.pdf\".into(), ..Default::default() }).await?;\nprintln!(\"{response:?}\");"
}

What you can do after this page

You should now be able to perform every operation in this area and understand why the request shape matters. Continue to another tutorial area or use the reference pages when you need exact configuration and error behaviour.