|
| 1 | +--- |
| 2 | +title: cf-r2-sdk |
| 3 | +pcx_content_type: example |
| 4 | +--- |
| 5 | + |
| 6 | +import { Render } from "~/components"; |
| 7 | + |
| 8 | +:::note |
| 9 | + |
| 10 | +cf-r2-sdk is a community-maintained Rust SDK. For questions or issues, refer to the [GitHub repository](https://github.com/Myxogastria0808/cf-r2-sdk). |
| 11 | + |
| 12 | +::: |
| 13 | + |
| 14 | +<Render file="keys" product="r2" /> |
| 15 | +<br /> |
| 16 | + |
| 17 | +This example uses the [cf-r2-sdk](https://crates.io/crates/cf-r2-sdk) crate, an unofficial Cloudflare R2 SDK with built-in support for uploading, downloading, and deleting binary data or files. |
| 18 | + |
| 19 | +## Why use an SDK? |
| 20 | + |
| 21 | +While you can interact with R2 using raw HTTP requests or the [aws-sdk-s3](/r2/examples/aws/aws-sdk-rust/) S3-compatible client, a dedicated SDK provides several advantages: |
| 22 | + |
| 23 | +- **Simplified API** – Provides Rust APIs for common R2 operations such as uploading, downloading, listing, and deleting objects. |
| 24 | +- **Native Rust ergonomics** – Avoids the complexity of configuring an AWS SDK while keeping strong type safety and async support. |
| 25 | +- **Quick setup** – Requires only minimal configuration: bucket name, endpoint, and credentials. |
| 26 | +- **Focused on R2** – Designed specifically around Cloudflare R2’s S3-compatible API surface. |
| 27 | + |
| 28 | +For more details, see the [cf-r2-sdk documentation](https://docs.rs/cf-r2-sdk/). |
| 29 | + |
| 30 | +## Installation |
| 31 | + |
| 32 | +```bash |
| 33 | +cargo add cf-r2-sdk |
| 34 | +``` |
| 35 | + |
| 36 | +## How to use |
| 37 | + |
| 38 | +The following example demonstrates how to configure the client and perform basic object operations against Cloudflare R2. |
| 39 | + |
| 40 | +#### 1. Create an R2 client |
| 41 | + |
| 42 | +Set the "bucket name", "access key id", "secret access key", "endpoint url", and "region". |
| 43 | + |
| 44 | +The default value of `region` is `"auto"` (this field is optional). |
| 45 | + |
| 46 | +```rust |
| 47 | +// create a client object |
| 48 | +let object: Result<cf_r2_sdk::operator::Operator, cf_r2_sdk::error::Error> = Builder::new() |
| 49 | + .set_bucket_name("bucket_name") |
| 50 | + .set_access_key_id("access_key_id") |
| 51 | + .set_secret_access_key("secret_access_key") |
| 52 | + .set_endpoint("endpoint_url") |
| 53 | + .set_region("region") |
| 54 | + .create_client_result(); |
| 55 | +``` |
| 56 | + |
| 57 | +#### 2. Operate R2 object storage |
| 58 | + |
| 59 | +**upload binary data** |
| 60 | + |
| 61 | +```rust |
| 62 | +let _ = object |
| 63 | + .upload_binary("<file name (key)> as &str", "<mime type> as &str", "<binary data> as &[u8]", "<cache> as Option<&str> (None is 'no-cache')") |
| 64 | + .await.unwrap(); |
| 65 | +``` |
| 66 | + |
| 67 | +**upload file** |
| 68 | + |
| 69 | +```rust |
| 70 | +let _ = object |
| 71 | + .upload_file("<file name (key)> as &str", "<mime type> as &str", "<file path> as &str", "<cache> as Option<&str> (None is "no-cache")") |
| 72 | + .await.unwrap(); |
| 73 | +``` |
| 74 | + |
| 75 | +**download binary data** |
| 76 | + |
| 77 | +```rust |
| 78 | +let binary: Vec<u8> = object.download("<file name (key)> as &str").await.unwrap(); |
| 79 | +``` |
| 80 | + |
| 81 | +**delete file** |
| 82 | + |
| 83 | +```rust |
| 84 | +let _ = object.delete("<file name (key)> as &str").await.unwrap(); |
| 85 | +``` |
| 86 | + |
| 87 | +**get file names vector (max get file names is 10)** |
| 88 | + |
| 89 | +```rust |
| 90 | +let file_names_list:Vec<String> = object.list_objects().await.unwrap(); |
| 91 | +``` |
| 92 | + |
| 93 | +## Example |
| 94 | + |
| 95 | +https://github.com/Myxogastria0808/cf-r2-sdk/blob/main/examples/simple.rs |
| 96 | + |
| 97 | +```rust |
| 98 | +use cf_r2_sdk::builder::Builder; |
| 99 | +use cf_r2_sdk::error::Error; |
| 100 | +use dotenvy::dotenv; |
| 101 | +use std::env; |
| 102 | + |
| 103 | +#[tokio::main(flavor = "current_thread")] |
| 104 | +async fn main() -> Result<(), Error> { |
| 105 | + // load .env file |
| 106 | + dotenv().expect(".env file not found."); |
| 107 | + // insert a environment variable |
| 108 | + let bucket_name = env::var("BUCKET_NAME").expect("BUCKET_NAME not found in .env file."); |
| 109 | + let endpoint_url: String = |
| 110 | + env::var("ENDPOINT_URL").expect("ENDPOINT_URL not found in .env file."); |
| 111 | + let access_key_id: String = |
| 112 | + env::var("ACCESS_KEY_ID").expect("ACCESS_KEY_ID not found in .env file."); |
| 113 | + let secret_access_key: String = |
| 114 | + env::var("SECRET_ACCESS_KEY").expect("SECRET_ACCESS_KEY not found in .env file."); |
| 115 | + let region: String = env::var("REGION").expect("REGION not found in .env file."); |
| 116 | + |
| 117 | + let object: cf_r2_sdk::operator::Operator = Builder::new() |
| 118 | + .set_bucket_name(bucket_name) |
| 119 | + .set_access_key_id(access_key_id) |
| 120 | + .set_secret_access_key(secret_access_key) |
| 121 | + .set_endpoint(endpoint_url) |
| 122 | + .set_region(region) |
| 123 | + .create_client_result()?; |
| 124 | + |
| 125 | + // upload binary data |
| 126 | + object |
| 127 | + .upload_binary("simple.txt", "text/plain", b"Hello, World!", None) |
| 128 | + .await?; |
| 129 | + Ok(()) |
| 130 | +} |
| 131 | +``` |
| 132 | + |
| 133 | +## Related resources |
| 134 | + |
| 135 | +- [cf-r2-sdk documentation](https://docs.rs/cf-r2-sdk/) |
| 136 | +- [GitHub repository](https://github.com/Myxogastria0808/cf-r2-sdk) |
| 137 | +- [Crates.io package](https://crates.io/crates/cf-r2-sdk) |
0 commit comments