共用方式為


建立一個使用 Azure DocumentDB 的 Rust 控制台應用程式

在本指南中,你要建立一個 Rust 主控台應用程式來連接到 Azure DocumentDB 叢集。 本指南涵蓋設定您的開發環境,使用適用於 Rust 的 Azure SDK 的 azure_identity 模組進行驗證,並管理資料庫中的文件。

先決條件

  • Azure 訂用帳戶

    • 如果您沒有 Azure 訂用帳戶,請建立 免費帳戶
  • 一個現有的 Azure DocumentDB 叢集

  • 為叢集設定 Microsoft Entra 驗證,且您的身分識別已獲授與 root 角色。

  • 最新版的 Python

設定主控台應用程式

接下來,建立新的主控台應用程式專案,並匯入必要的函式庫來驗證您的叢集。

  1. 使用 cargo new建立新的 Rust 專案。

    cargo new mongodb-app
    cd mongodb-app
    
  2. azure_core 壓縮容器格式 (Crate) 新增至您的相依性。

    cargo add azure_core
    
  3. 新增用於驗證的 azure_identity 壓縮容器格式 (Crate)。

    cargo add azure_identity
    
  4. 新增mongodb驅動程式函式庫以與您的叢集互動。

    cargo add mongodb
    
  5. 針對非同步作業,另新增支援的 tokiofuturesserde 壓縮容器格式 (Crate)。

    cargo add tokio --features full
    cargo add futures
    cargo add serde --features derive
    

連接至叢集

現在,使用 Azure.Identity 庫取得 TokenCredential,以用來連線到您的叢集。 官方 MongoDB 驅動程式有一個特殊的介面,必須實作才能從 Microsoft Entra 取得令牌,以在連線到叢集時使用。

  1. 開啟您的 main.rs 檔案,並匯入必要的壓縮容器格式 (Crate) 和模組。

    use azure_core::credentials::TokenCredential;
    use azure_identity::DefaultAzureCredential;
    use futures::{FutureExt, TryStreamExt};
    use mongodb::{
        Client,
        bson::doc,
        options::{
            AuthMechanism, ClientOptions, Credential,
            oidc::{self, IdpServerResponse},
        },
    };
    use serde::{Deserialize, Serialize};
    
  2. 建立主要的異步函式,並進行必要的錯誤處理。

    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
    
        Ok(())
    }
    
  3. 建立結構 azure_identity::DefaultAzureCredential的新實例。

    let credential = DefaultAzureCredential::new()?;
    
  4. 建立認證回呼以處理來自 MongoDB 用戶端的令牌要求。

    let azure_identity_token_credential = Credential::builder()
        .mechanism(AuthMechanism::MongoDbOidc)
        .oidc_callback(oidc::Callback::machine(move |_| {
            let azure_credential = credential.clone();
            async move {
                let access_token = azure_credential
                    .get_token(&["https://ossrdbms-aad.database.windows.net/.default"])
                    .await
                    .map_err(|e| {
                        mongodb::error::Error::custom(format!("Azure token error: {}", e))
                    })?;
                Ok(IdpServerResponse::builder()
                    .access_token(access_token.token.secret().to_owned())
                    .build())
            }
            .boxed()
        }))
        .build()
        .into();
    
  5. 使用叢集的名稱、配置和全域端點,定義來自叢集的統一資源指標(URI)。

    let cluster_name = "<azure-documentdb-cluster-name>";
    
    let uri = format!(
        "mongodb+srv://{}.global.mongocluster.cosmos.azure.com/",
        cluster_name
    );
    
  6. 使用最佳做法設定、您的 URI 和認證回撥來建構 mongodb::ClientOptions 執行個體。

    let mut client_options = ClientOptions::parse(uri).await?;
    
    client_options.connect_timeout = Some(std::time::Duration::from_secs(120));
    client_options.tls = Some(mongodb::options::Tls::Enabled(Default::default()));
    client_options.retry_writes = Some(true);
    
    client_options.credential = Some(azure_identity_token_credential);
    
  7. 使用建構的設定創建mongodb::Client的新實例。

    let client = Client::with_options(client_options)?;
    
    println!("Client created");
    

執行一般作業

最後,使用官方程式庫處理資料庫、集合和文件的常見工作。 在這裡,您可以使用與 MongoDB 或 DocumentDB 互動的相同類別和方法來管理您的集合和專案。

  1. 建立一個 Rust 結構體,以代表你的 Product 文件,並支援 serde 序列化。

    #[derive(Serialize, Deserialize, Debug)]
    struct Product {
        _id: String,
        category: String,
        name: String,
        quantity: i32,
        price: f64,
        clearance: bool,
    }
    
  2. 依名稱取得您資料庫的參考。

    let database = client.database("<database-name>");
    
    println!("Database pointer created");
    
  3. 取得您集合的參考。

    let collection = database.collection::<Product>("<collection-name>");
    
    println!("Collection pointer created");
    
  4. 使用 collection.update_one 建立文件,然後將其 upsert 到集合中。

    let document = Product {
        _id: "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb".to_string(),
        category: "gear-surf-surfboards".to_string(),
        name: "Yamba Surfboard".to_string(),
        quantity: 12,
        price: 850.00,
        clearance: false,
    };
    
    let response = collection
        .update_one(
            doc! { "_id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb" },
            doc! { "$set": mongodb::bson::to_document(&document)? },
        )
        .upsert(true)
        .await?;
    
    println!("Documents upserted count:\t{}", response.modified_count);
    
  5. 使用 collection.find_one 和篩選從集合讀取特定檔。

    let document = collection
        .find_one(doc! { "_id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb" })
        .await?;
    
    println!("Read document _id:\t{:#?}", document.unwrap()._id);
    
  6. 使用 collection.find查詢符合篩選條件的多個檔。

    let filter = doc! { "category": "gear-surf-surfboards" };
    
    let mut cursor = collection.find(filter).await?;
    
    while let Some(document) = cursor.try_next().await? {
        println!("Found document:\t{:#?}", document);
    }