Docs Menu
Docs Home
/ / /
Rust Driver
/

Asynchronous and Synchronous APIs

On this page

  • Overview
  • Configure the Asynchronous Runtime
  • Tokio Runtime Example
  • Configure the Synchronous API
  • Synchronous Code Example
  • Use Both Asynchronous and Synchronous APIs
  • Additional Information
  • API Documentation

In this guide, you can learn about the Rust driver's asynchronous and synchronous APIs. This guide explains how to enable the available APIs and structure your code to use each.

The Rust driver supports tokio and async-std, two popular asynchronous runtime crates. By default, the driver uses the tokio asynchronous runtime, but you can select a specific runtime by adding feature flags to the mongodb dependency in your Cargo.toml file.

The driver also includes a synchronous API for use cases that require blocking, or when parallelism is not necessary. You can select the synchronous API by adding feature flags to the mongodb dependency in your Cargo.toml file.

The driver uses the tokio runtime by default. You can explicitly choose a runtime by adding the "tokio-runtime" or "async-std-runtime" feature flags to the mongodb dependency.

Select from the following tabs to see how to add feature flags for each corresponding crate:

For more information on installing the driver and adding feature flags, see the Download and Install step of the Quick Start.

The following code uses the task module from the tokio crate to create separate, concurrent tasks for multiple data operations:

let client = Client::with_uri_str("<connection string>").await?;
let some_data = doc! { "title": "1984", "author": "George Orwell" };
for i in 0..5 {
let client_ref = client.clone();
let somedata_ref = some_data.clone();
task::spawn(async move {
let collection = client_ref
.database("items")
.collection::<Document>(&format!("coll{}", i));
collection.insert_one(somedata_ref, None).await
});
}

The driver also provides a blocking, synchronous API. To use the synchronous API, add the either the "sync" or "tokio-sync" feature flag to the mongodb dependency.

Select from the following tabs to see how to add feature flags for each corresponding crate:

When using the synchronous API, use types from the mongodb::sync module to perform operations. The following code uses the sync module to insert data into a collection using the synchronous API. When the insert_one method runs inside the for loop, the driver waits for each request to complete before continuing.

use mongodb::sync::Client;
fn main() {
let client = Client::with_uri_str("<connection string>")?;
let some_data = doc! { "title": "1984", "author": "George Orwell" };
for i in 0..5 {
let client_ref = client.clone();
let somedata_ref = some_data.clone();
let collection = client_ref
.database("items")
.collection::<Document>(&format!("coll{}", i));
collection.insert_one(somedata_ref, None);
}
}

You can use both asynchronous and synchronous APIs in the same application. For example, to enable both tokio runtimes, you can add the tokio dependency to your dependencies list, and add the "tokio-sync" flag to the mongodb dependency:

[dependencies]
futures = "0.3.28"
tokio = {version = "1.32.0", features = ["full"]}
[dependencies.mongodb]
version = "2.8.2"
features = ["tokio-sync"]

For more information about the concepts in this guide, see the following pages:

To learn more about the methods and types mentioned in this guide, see the following API documentation:

← Performance Considerations