Rust

作者 appwriteab3c90b37c95無授權條款10 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫7 週前更新

Appwrite Rust SDK skill. Use when building server-side Rust applications with Appwrite. Covers async client setup with API keys, user management, TablesDB database/table/row operations, file storage, function executions, permissions, queries, and error handling. Uses the crates.io `appwrite` package and Tokio.

AI 產生的概覽

指導使用 Appwrite SDK 進行伺服器端 Rust 開發,涵蓋用戶端設定、使用者、TablesDB、儲存、函式與錯誤處理。

功能
此技能提供使用 Appwrite SDK 建置伺服器端 Rust 應用程式的參考說明與程式碼範例。內容涵蓋使用 API 金鑰與 Tokio 的非同步用戶端設定、使用者管理、TablesDB 的資料庫、資料表、欄與資料列操作、查詢、檔案儲存、函式執行、權限以及錯誤處理。它產出的是指引與程式碼片段,而非指令碼或產生的檔案。
適用情境
在撰寫或審查整合 Appwrite 的伺服器端 Rust 程式碼時使用。它適合在 Rust 後端中處理 Appwrite 使用者、資料庫、儲存桶、函式執行或權限的任務。
執行需求
需要 crates.io 的 appwrite 套件、啟用 full 功能的 Tokio 以及 serde_json。伺服器端驗證需要 Appwrite 端點、專案 ID 與 API 金鑰,並需要連線至 Appwrite 服務的網路存取。不附帶指令碼,僅為說明文件。

Appwrite Rust SDK

Installation

bash
cargo add appwritecargo add tokio --features fullcargo add serde_json

Or add dependencies manually:

toml
[dependencies]appwrite = "0.3.0"tokio = { version = "1", features = ["full"] }serde_json = "1"

Setting Up the Client

The Rust SDK is async. Use it from a Tokio runtime and authenticate server-side with an API key.

rust
use appwrite::Client;use std::env;
let client = Client::new()    .set_endpoint("https://<REGION>.cloud.appwrite.io/v1")    .set_project(env::var("APPWRITE_PROJECT_ID")?)    .set_key(env::var("APPWRITE_API_KEY")?);

Complete server skeleton

rust
use appwrite::query::Query;use appwrite::services::Users;use appwrite::Client;use std::env;
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> {    let client = Client::new()        .set_endpoint("https://<REGION>.cloud.appwrite.io/v1")        .set_project(env::var("APPWRITE_PROJECT_ID")?)        .set_key(env::var("APPWRITE_API_KEY")?);
    let users = Users::new(&client);    let _list = users        .list(Some(vec![Query::limit(25).to_string()]), None, Some(true))        .await?;
    Ok(())}

Code Examples

User Management

rust
use appwrite::id::ID;use appwrite::query::Query;use appwrite::services::Users;
let users = Users::new(&client);
// Create userlet _user = users    .create(        ID::unique(),        Some("[email protected]"),        None,        Some("password123"),        Some("User Name"),    )    .await?;
// List userslet _list = users    .list(Some(vec![Query::limit(25).to_string()]), None, Some(true))    .await?;
// Get userlet _fetched = users.get("[USER_ID]").await?;
// Delete userusers.delete("[USER_ID]").await?;

Database Operations

Note: Use TablesDB for new code. Only use Databases if the existing project explicitly depends on the legacy Databases API.

Rust SDK calling convention: Methods are async, use positional parameters, and represent optional API parameters as Option<T>. Pass None for optional values you are not setting.

rust
use appwrite::id::ID;use appwrite::permission::Permission;use appwrite::query::Query;use appwrite::role::Role;use appwrite::services::TablesDB;use serde_json::json;
let tables_db = TablesDB::new(&client);
// Create databaselet _database = tables_db    .create(ID::unique(), "My Database", Some(true))    .await?;
// Create tablelet _table = tables_db    .create_table(        "[DATABASE_ID]",        ID::unique(),        "articles",        Some(vec![            Permission::read(Role::any()).to_string(),            Permission::create(Role::users(None)).to_string(),        ]),        Some(true),        Some(true),        None,        None,    )    .await?;
// Create rowlet _row = tables_db    .create_row(        "[DATABASE_ID]",        "[TABLE_ID]",        ID::unique(),        json!({            "title": "Hello World",            "done": false        }),        None,        None,    )    .await?;
// Query rowslet _rows = tables_db    .list_rows(        "[DATABASE_ID]",        "[TABLE_ID]",        Some(vec![            Query::equal("done", false).to_string(),            Query::limit(10).to_string(),        ]),        None,        Some(true),        None,    )    .await?;
// Get rowlet _row = tables_db    .get_row("[DATABASE_ID]", "[TABLE_ID]", "[ROW_ID]", None, None)    .await?;
// Update rowlet _updated = tables_db    .update_row(        "[DATABASE_ID]",        "[TABLE_ID]",        "[ROW_ID]",        Some(json!({ "done": true })),        None,        None,    )    .await?;
// Delete rowtables_db    .delete_row("[DATABASE_ID]", "[TABLE_ID]", "[ROW_ID]", None)    .await?;
String Column Types

Note: The legacy string column type is deprecated. Use explicit string column types for new tables.

TypeMax charactersIndexingStorage
varchar16,383Full index (if size <= 768)Inline in row
text16,383Prefix onlyOff-page
mediumtext4,194,303Prefix onlyOff-page
longtext1,073,741,823Prefix onlyOff-page
  • varchar is stored inline and counts toward the 64 KB row size limit. Prefer it for short, indexed fields like names, slugs, and identifiers.
  • text, mediumtext, and longtext are stored off-page, so they do not consume the row size budget. size is not required for these types.
rust
use appwrite::enums::{OrderBy, TablesDBIndexType};
// Short, indexed stringlet _title = tables_db    .create_varchar_column(        "[DATABASE_ID]",        "[TABLE_ID]",        "title",        255,        true,        None,        None,        None,    )    .await?;
// Off-page longer textlet _summary = tables_db    .create_text_column("[DATABASE_ID]", "[TABLE_ID]", "summary", false, None, None, None)    .await?;
let _body = tables_db    .create_mediumtext_column("[DATABASE_ID]", "[TABLE_ID]", "body", false, None, None, None)    .await?;
let _raw_data = tables_db    .create_longtext_column("[DATABASE_ID]", "[TABLE_ID]", "raw_data", false, None, None, None)    .await?;
// Index only the varchar column fully.let _index = tables_db    .create_index(        "[DATABASE_ID]",        "[TABLE_ID]",        "title_idx",        TablesDBIndexType::Key,        vec!["title"],        Some(vec![OrderBy::Asc]),        Some(vec![255]),    )    .await?;

Query Methods

TablesDB methods accept Option<Vec<String>> for queries. Convert each Query to a string.

rust
use appwrite::query::Query;use serde_json::Value;
let queries = vec![    Query::equal("status", "published").to_string(),    Query::not_equal("archived", true).to_string(),    Query::greater_than("views", 100).to_string(),    Query::less_than_equal("priority", 5).to_string(),    Query::between("score", 1, 100).to_string(),    Query::is_not_null("publishedAt").to_string(),    Query::search("title", "rust appwrite").to_string(),    Query::contains("tags", "rust").to_string(),    Query::order_desc("$createdAt").to_string(),    Query::limit(25).to_string(),    Query::offset(50).to_string(),];
let multi_value = Query::equal(    "status",    Value::Array(vec![        Value::String("draft".to_string()),        Value::String("published".to_string()),    ]),).to_string();

File Storage

rust
use appwrite::id::ID;use appwrite::input_file::InputFile;use appwrite::permission::Permission;use appwrite::query::Query;use appwrite::role::Role;use appwrite::services::Storage;
let storage = Storage::new(&client);
// Create bucketlet _bucket = storage    .create_bucket(        ID::unique(),        "Uploads",        Some(vec![            Permission::read(Role::any()).to_string(),            Permission::create(Role::users(None)).to_string(),        ]),        Some(true),        Some(true),        Some(30_000_000),        Some(vec!["jpg".to_string(), "png".to_string(), "pdf".to_string()]),        None,        Some(true),        Some(true),        Some(true),    )    .await?;
// Upload from disklet input = InputFile::from_path("avatar.png", Some("image/png")).await?;let _file = storage    .create_file(        "[BUCKET_ID]",        ID::unique(),        input,        Some(vec![Permission::read(Role::any()).to_string()]),    )    .await?;
// Upload from byteslet input = InputFile::from_bytes(b"hello".to_vec(), "hello.txt", Some("text/plain"));let _file = storage.create_file("[BUCKET_ID]", ID::unique(), input, None).await?;
// List fileslet _files = storage    .list_files("[BUCKET_ID]", Some(vec![Query::limit(10).to_string()]), None, Some(true))    .await?;
// Download file byteslet _content = storage    .get_file_download("[BUCKET_ID]", "[FILE_ID]", None)    .await?;
// Delete filestorage.delete_file("[BUCKET_ID]", "[FILE_ID]").await?;

Functions

rust
use appwrite::enums::ExecutionMethod;use appwrite::query::Query;use appwrite::services::Functions;use serde_json::json;
let functions = Functions::new(&client);
// List functionslet _functions = functions    .list(Some(vec![Query::limit(25).to_string()]), None, Some(true))    .await?;
// Execute functionlet _execution = functions    .create_execution(        "[FUNCTION_ID]",        Some(r#"{"hello":"world"}"#),        Some(false),        Some("/jobs/sync"),        Some(ExecutionMethod::POST),        Some(json!({ "content-type": "application/json" })),        None,    )    .await?;
// Get executionlet _execution = functions    .get_execution("[FUNCTION_ID]", "[EXECUTION_ID]")    .await?;

Permissions

rust
use appwrite::permission::Permission;use appwrite::role::Role;
let permissions = vec![    Permission::read(Role::any()).to_string(),    Permission::create(Role::users(None)).to_string(),    Permission::update(Role::user("[USER_ID]", None)).to_string(),    Permission::delete(Role::team("[TEAM_ID]", Some("owner"))).to_string(),];

Error Handling

rust
match users.get("[USER_ID]").await {    Ok(user) => {        let _user = user;    }    Err(error) if error.status_code() == 404 => {        eprintln!("User not found: {}", error.get_message());    }    Err(error) => {        eprintln!("Appwrite error {}: {}", error.status_code(), error.get_message());        return Err(Box::new(error) as Box<dyn std::error::Error>);    }}

Common Pitfalls

  • The Rust SDK is currently a server-side SDK. Prefer TypeScript/Web, Flutter, Apple, Android, or React Native SDKs for browser/mobile client auth flows.
  • Always await service calls.
  • Pass None for optional parameters you are not using.
  • Use TablesDB, not legacy Databases, for new database code.
  • Convert queries with .to_string() before passing them to APIs that expect Option<Vec<String>>.
  • Use serde_json::json!({...}) for row data and JSON bodies.
  • Use InputFile::from_path(...).await? or InputFile::from_bytes(...) for uploads.

來源與署名

來源:appwrite/claude-plugin位於skills/rust提交ab3c90b

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架