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 Cosmos DB for MongoDB vCore 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 existing Azure Cosmos DB for MongoDB (vCore) cluster.
- If you don't have an Azure subscription, create an account for free.
- If you have an existing Azure subscription, create a new Azure Cosmos DB for MongoDB vCore cluster.
The latest version of the Azure CLI in Azure Cloud Shell.
- If you prefer to run CLI reference commands locally, sign in to the Azure CLI by using the
az logincommand.
- If you prefer to run CLI reference commands locally, sign in to the Azure CLI by using the
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 cosmos-mongodb-app cd cosmos-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-cosmos-db-mongodb-vcore-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); }