Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
In this guide, you create a Rust console application to connect to an Azure DocumentDB cluster. The guide covers setting up your development environment, using the azure_identity crate from the Azure SDK for Rust to authenticate, and managing documents within the database.
Prerequisites
An Azure subscription
- If you don't have an Azure subscription, create a free account
An existing Azure DocumentDB cluster
- If you don't have a cluster, create a new cluster
Use the Bash environment in Azure Cloud Shell. For more information, see Get started with Azure Cloud Shell.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you're running on Windows or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish the authentication process, follow the steps displayed in your terminal. For other sign-in options, see Authenticate to Azure using Azure CLI.
When you're prompted, install the Azure CLI extension on first use. For more information about extensions, see Use and manage extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the latest version, run az upgrade.
Microsoft Entra authentication configured for the cluster with your identity granted
rootrole.- To enable Microsoft Entra authentication, review the configuration guide.
Latest version of Python.
Configure your console application
Next, create a new console application project and import the necessary libraries to authenticate to your cluster.
Create a new Rust project using
cargo new.cargo new mongodb-app cd mongodb-appAdd the
azure_corecrate to your dependencies.cargo add azure_coreAdd the
azure_identitycrate for authentication.cargo add azure_identityAdd the
mongodbdriver crate to interact with your cluster.cargo add mongodbFor async operations, also add the supporting
tokio,futures, andserdecrates.cargo add tokio --features full cargo add futures cargo add serde --features derive
Connect to the cluster
Now, use the Azure.Identity library to get a TokenCredential to use to connect to your cluster. The official MongoDB driver has a special interface that must be implemented to obtain tokens from Microsoft Entra for use when connecting to the cluster.
Open your main.rs file and import the necessary crates and modules.
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};Create the main async function with the necessary error handling.
#[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { Ok(()) }Create a new instance of struct
azure_identity::DefaultAzureCredential.let credential = DefaultAzureCredential::new()?;Create a credential callback to handle token requests from the MongoDB client.
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();Define a uniform resource indicator (URI) from your cluster using its name, scheme, and the global endpoint.
let cluster_name = "<azure-documentdb-cluster-name>"; let uri = format!( "mongodb+srv://{}.global.mongocluster.cosmos.azure.com/", cluster_name );Construct a
mongodb::ClientOptionsinstance using best practices configuration, your URI, and the credential callback.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);Create a new instance of
mongodb::Clientusing the constructed settings.let client = Client::with_options(client_options)?; println!("Client created");
Perform common operations
Finally, use the official library to perform common tasks with databases, collections, and documents. Here, you use the same classes and methods you would use to interact with MongoDB or DocumentDB to manage your collections and items.
Create a Rust struct to represent your
Productdocuments withserdeserialization support.#[derive(Serialize, Deserialize, Debug)] struct Product { _id: String, category: String, name: String, quantity: i32, price: f64, clearance: bool, }Get a reference to your database by name.
let database = client.database("<database-name>"); println!("Database pointer created");Get a reference to your collection.
let collection = database.collection::<Product>("<collection-name>"); println!("Collection pointer created");Create a document using
collection.update_oneand upsert it into the collection.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);Read a specific document from the collection using
collection.find_oneand a filter.let document = collection .find_one(doc! { "_id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb" }) .await?; println!("Read document _id:\t{:#?}", document.unwrap()._id);Query for multiple documents matching a filter using
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); }