We posted a series of hello world examples coded using our SDK and showed how easy it was for developers to get started with the Oracle NoSQL Database cloud. In this post, I will show the same hello world example coded in RUST, and if you are a rust developer and already have access to the Oracle Cloud, I believe you will be up and running in 10 minutes or less by using the Oracle NoSQL Database Cloud service with Rust SDK.
In the very first “hello world” post, we also talked about why you might want to use a NoSQL Database for certain applications. For that discussion, you can check out the post 15-minutes-to-hello-world. The remainder of this post will focus on writing rust code for your first Oracle NoSQL Database cloud application.
Getting Started with the Oracle NoSQL Database Cloud Service
The Oracle NoSQL Database Cloud Service is a server-less, fully managed data store that delivers predictable single-digit response times and allows the application to scale on-demand via provisioning API calls. There are five simple steps to getting started with the Oracle NoSQL Database Cloud Service.
- Donwload the Oracle NoSQL Database Rust SDK
- Create a compartment for your table (if you do not want your table in the root compartment)
- Connect to the Oracle NoSQL Database cloud service
- Create a table with provisioned reads/sec, writes/sec, and GB storage
- Write data to the table and read data from the table
Furthermore, you can use free cloud credits to do all of this and not pay a single penny.
Once you have created a cloud account, you can either navigate to the Oracle NoSQL Database table management console or if you are like most developers, quickly move onto writing your first “hello world” code. You can write your first “hello world” program using Python, Node.js, Java, Go, and other popular programming languages. I will use Rust for the remainder of this blog.
Download the Oracle NoSQL Database Rust SDK
Since access to the Oracle NoSQL Cloud Service is via HTTP, you can run your application directly on your laptop and connect to the database service over the internet. While I would never recommend using the internet as a network transport for performance-sensitive applications, it works perfectly for our “hello world” example. In fact, it is likely that you would want to deploy a real application by running inside your own tenancy, co-located in the same Oracle Cloud Infrastructure region as your Oracle NoSQL table, and use the Oracle Cloud Infrastructure Service Gateway to connect to the NoSQL Cloud Service.
The Rust SDK for Oracle NoSQL Database is published as a Rust crate. It is recommended to use standard Rust mechanism for usage of this crate. So go to https://crates.io/crates/oracle-nosql-rust-sdk
To do so, add the following dependency to your Cargo.toml file:
[dependencies]
oracle-nosql-rust-sdk = "0.1"
tokio = { version = "1.38.0", features = ["full"] }
The SDK supplies and uses Rust async methods. It is why we are adding the tokio dependency.
As a prerequisite, you must install Rust 1.78 or later
- Download and install a Rust binary release suitable for your system. See the install and setup instructions on that page.
- Install additional package needed to build the executable. The current version of the SDK is using the vendored features on openssl. It builds the entire openssl library into your executable.
Create a Compartment for Your Table
If you would like your table to be created in your own compartment (e.g. demonosql) rather than the root compartment
1) On the left side drop-down (left of Oracle Cloud banner), go to Identity & Security and then Compartments.

2) Click on Create Compartment. This opens up a new window.
Enter demonosql as compartment name, enter a description,, and hit ‘Create Compartment’ button at bottom of the window. The parent compartment will display your current parent compartment — this does not need to be changed.

3) Copy the Compartment OCID. It will be used later.

Connect to the Oracle NoSQL Database Cloud Service
The Oracle NoSQL Database Cloud Service uses the Oracle Cloud Infrastructure native cloud Identity Access Manager (IAM) for authentication and authorization. In the oracle-nosql-rust-sdk documentation, (https://docs.rs/oracle-nosql-rust-sdk/latest/oracle_nosql_rust_sdk/) , you can follow the tutorial called Connecting an Application to Oracle NoSQL Database Cloud Service. You can learn all about the Handle class, which is what I will use to instantiate a connection to the cloud service and authenticate. In this example, I will use Authorizing with Instance Principal.
Instance Principal is an IAM service feature that enables instances to be authorized actors (or principals) to perform actions on service resources. Each compute instance has its own identity, and it authenticates using the certificates that are added to it.
- First, call the function Handle::builder() – This method will perform authentication with the Oracle NoSQL Cloud Service and return a handle to the service.
- Followed by the function TableRequest – This function will create a table with two columns; an ID column of type LONG and a content column of type JSON.
- Call the following functions:
- PutRequest – This function will write a single record to the hello world table.
- GetRequest – This function will read a single record from the hello world table and return this record as a JSON string.
- DeleteRequest – this function will delete a single record from the hello world table.
- Finally, call the function TableRequest to drop the hello world table
use oracle_nosql_rust_sdk::types::*;
use oracle_nosql_rust_sdk::DeleteRequest;
use oracle_nosql_rust_sdk::GetRequest;
use oracle_nosql_rust_sdk::Handle;
use oracle_nosql_rust_sdk::HandleMode;
use oracle_nosql_rust_sdk::TableRequest;
use oracle_nosql_rust_sdk::PutRequest;
use std::error::Error;
use std::time::Duration;
use std::env;
// Example way to use multiple threaded tokio runtime
#[tokio::main(flavor = "multi_thread", worker_threads = 4)]
async fn main() -> Result<(), Box
> {
//let compid = "ocid1.compartment.oc1..aaaaaaaa4mlehopmvdluv2wjcdp4tnh2ypjz3nhhpahb4ss7yvxaa3be3diq".to_string();
let compid = env::var("NOSQL_COMPID")?;
println!("COMPID={:?}", compid);
println!("Creating new handle...");
let handle = Handle::builder()
.mode(HandleMode::Cloud)?
.cloud_region("us-ashburn-1")?
.cloud_auth_from_instance()?
.from_environment()?
.timeout(Duration::from_secs(15))?
.build()
.await?
;
// Create an example table
TableRequest::new("hello_world")
.statement(
"CREATE TABLE IF NOT EXISTS hello_world (id LONG, content JSON, PRIMARY KEY(id))",
)
// the following line is only needed for Cloud mode
.limits(&TableLimits::provisioned(10, 10, 1))
.compartment_id(&compid)
.execute(&handle)
.await?
// wait up to 15 seconds for table to be created
.wait_for_completion_ms(&handle, 15000, 500)
.await?
;
println!("Table hello_world created");
// Put a record into the table
// Note: ttl is a Duration, but internally is converted to a whole number of
// hours or days. Minimum duration is one hour.
let content = MapValue::new()
.column("name", "Jane".to_string())
.column("street", Some("321 Main Street".to_string()))
.column("city", "Anytown".to_string());
println!("Content={:?}", content);
let putres = PutRequest::new("hello_world")
.timeout(&Duration::from_millis(3000))
.value(MapValue::new().i32("id", 10).column("content", content))
.ttl(&Duration::new(7200, 0))
.compartment_id(&compid)
.execute(&handle)
.await?
;
println!("PutResult={:?}", putres);
// PutResult should have a version
if putres.version().is_none() {
return Err("PutRequest should have returned a version, but did not".into());
}
// Get the record back
let getres = GetRequest::new("hello_world")
.key(MapValue::new().i32("id", 10))
.consistency(Consistency::Eventual)
.compartment_id(&compid)
.execute(&handle)
.await?
;
println!("GetResult={:?}", getres);
// GetResult should have a version
if getres.version().is_none() {
return Err("GetRequest should have returned a version, but did not".into());
}
// Example of how to remove a record with if_version
let delres = DeleteRequest::new("hello_world", MapValue::new().i32("id", 1))
.if_version(&getres.version().unwrap())
.compartment_id(&compid)
.execute(&handle)
.await?
;
println!("delres={:?}", delres);
// Drop the table
TableRequest::new("hello_world")
.statement("drop table if exists hello_world")
.compartment_id(&compid)
.execute(&handle)
.await?
.wait_for_completion_ms(&handle, 15000, 500)
.await?
;
println!("Table hello_world dropped");
Ok(())
}
If you take the code above and place it in a file entitled src/main.rs and set your env variable NOSQL_COMPID to the compartment OCID where you want your table created, you can run this file as specified below:
$ cargo new myapp
Creating binary (application) `myapp` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
$ cd myapp/
# add the dependency oracle-nosql-rust-sdk = { version = "0.1" }
$ cat Cargo.tocl
[package]
name = "myapp"
version = "0.1.0"
edition = "2021"
[dependencies]
oracle-nosql-rust-sdk = { version = "0.1" }
tokio = { version = "1.38.0", features = ["full"] }
# copy the code
$ vi src/main.rs
$ cargo build
$ export NOSQL_COMPID="
" ; cargo run
Creating new handle...
Table hello_world created
Content=MapValue { m: {"city": String("Anytown"), "name": String("Jane"), "street": String("321 Main Street")} }
PutResult=PutResult { version: Some([172, 237, 0, 5, 119, 44, 0, 32, 52, 94, 246, 30, 18, 210, 78, 107, 155, 94, 60, 154, 217, 146, 150, 133, 0, 0, 0, 0, 7, 173, 55, 245, 1, 3, 0, 0, 0, 12, 0, 0, 0, 2, 0, 0, 0, 141, 19, 128, 67, 133]), consumed: Some(Capacity { read_kb: 0, write_kb: 2, read_units: 0 }), generated_value: None, existing_modification_time: 0, existing_value: None, existing_version: None }
GetResult=GetResult { row: Some(MapValue { m: {"content": Map(MapValue { m: {"city": String("Anytown"), "name": String("Jane"), "street": String("321 Main Street")} }), "id": Long(10)} }), consumed: Some(Capacity { read_kb: 1, write_kb: 0, read_units: 1 }), modification_time: 1736869666425, expiration_time: 1736877600000, version: Some([172, 237, 0, 5, 119, 44, 0, 32, 52, 94, 246, 30, 18, 210, 78, 107, 155, 94, 60, 154, 217, 146, 150, 133, 0, 0, 0, 0, 7, 173, 55, 245, 1, 3, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 142, 19, 148, 192, 18]) }
delres=DeleteResult { success: false, consumed: Some(Capacity { read_kb: 1, write_kb: 0, read_units: 2 }), existing_modification_time: 0, existing_value: None, existing_version: None }
Table hello_world dropped
Delete succeeded.
Table hello_world dropped, table state is Dropped
For more information about the Rust SDK and pointers to more example code on Github, take a look here https://github.com/oracle/nosql-rust-sdk
If you have questions regarding this exercise, please send an email to oraclenosql-info_ww@oracle.com with “Hello World – Rust” in the subject line, and someone will get back to you as soon as possible.
