• Glossary
  • Support
  • Downloads
  • DataStax Home
Get Live Help
Expand All
Collapse All

DataStax Astra DB Serverless Documentation

    • Overview
      • Release notes
      • Astra DB FAQs
      • Astra DB glossary
      • Get support
    • Getting Started
      • Grant a user access
      • Load and retrieve data
        • Use DSBulk to load data
        • Use Data Loader in Astra Portal
      • Connect a driver
      • Build sample apps
      • Use integrations
        • Connect with DataGrip
        • Connect with DBSchema
        • Connect with JanusGraph
        • Connect with Strapi
    • Planning
      • Plan options
      • Database regions
    • Securing
      • Security highlights
      • Security guidelines
      • Default user permissions
      • Change your password
      • Reset your password
      • Authentication and Authorization
      • Astra DB Plugin for HashiCorp Vault
    • Connecting
      • Connecting private endpoints
        • AWS Private Link
        • Azure Private Link
        • GCP Private Endpoints
        • Connecting custom DNS
      • Connecting Change Data Capture (CDC)
      • Connecting CQL console
      • Connect the Spark Cassandra Connector to Astra
      • Drivers for Astra DB
        • Connecting C++ driver
        • Connecting C# driver
        • Connecting Java driver
        • Connecting Node.js driver
        • Connecting Python driver
        • Drivers retry policies
      • Connecting Legacy drivers
      • Get Secure Connect Bundle
    • Migrating
      • FAQs
      • Preliminary steps
        • Feasibility checks
        • Deployment and infrastructure considerations
        • Create target environment for migration
        • Understand rollback options
      • Phase 1: Deploy ZDM Proxy and connect client applications
        • Set up the ZDM Automation with ZDM Utility
        • Deploy the ZDM Proxy and monitoring
          • Configure Transport Layer Security
        • Connect client applications to ZDM Proxy
        • Manage your ZDM Proxy instances
      • Phase 2: Migrate and validate data
      • Phase 3: Enable asynchronous dual reads
      • Phase 4: Change read routing to Target
      • Phase 5: Connect client applications directly to Target
      • Troubleshooting
        • Troubleshooting tips
        • Troubleshooting scenarios
      • Additional resources
        • Glossary
        • Contribution guidelines
        • Release Notes
    • Managing
      • Managing your organization
        • User permissions
        • Pricing and billing
        • Audit Logs
        • Bring Your Own Key
          • BYOK AWS Astra DB console
          • BYOK GCP Astra DB console
          • BYOK AWS DevOps API
          • BYOK GCP DevOps API
        • Configuring SSO
          • Configure SSO for Microsoft Azure AD
          • Configure SSO for Okta
          • Configure SSO for OneLogin
      • Managing your database
        • Create your database
        • View your databases
        • Database statuses
        • Use DSBulk to load data
        • Use Data Loader in Astra Portal
        • Monitor your databases
        • Export metrics to third party
          • Export metrics via Astra Portal
          • Export metrics via DevOps API
        • Manage access lists
        • Manage multiple keyspaces
        • Using multiple regions
        • Terminate your database
      • Managing with DevOps API
        • Managing database lifecycle
        • Managing roles
        • Managing users
        • Managing tokens
        • Managing BYOK AWS
        • Managing BYOK GCP
        • Managing access list
        • Managing multiple regions
        • Get private endpoints
        • AWS PrivateLink
        • Azure PrivateLink
        • GCP Private Service
    • Astra CLI
    • DataStax Astra Block
      • FAQs
      • About NFTs
      • DataStax Astra Block for Ethereum quickstart
    • Developing with Stargate APIs
      • Develop with REST
      • Develop with Document
      • Develop with GraphQL
        • Develop with GraphQL (CQL-first)
        • Develop with GraphQL (Schema-first)
      • Develop with gRPC
        • gRPC Rust client
        • gRPC Go client
        • gRPC Node.js client
        • gRPC Java client
      • Develop with CQL
      • Tooling Resources
      • Node.js Document API client
      • Node.js REST API client
    • Stargate QuickStarts
      • Document API QuickStart
      • REST API QuickStart
      • GraphQL API CQL-first QuickStart
    • API References
      • DevOps REST API v2
      • Stargate Document API v2
      • Stargate REST API v2
  • DataStax Astra DB Serverless Documentation
  • Developing with Stargate APIs
  • Develop with gRPC
  • gRPC Rust client

gRPC Rust Client

Rust set-up

Set up a Rust project

Use the following command to initialize a Rust project in an empty directory:

cargo init

Two files will be created, Cargo.toml and src/main.rs.

Add dependencies

  1. Add required dependencies to the Cargo.toml file in your Rust project. You’ll need at least stargate-grpc and an async framework, such as tokio:

    [dependencies]
    stargate-grpc = "0.3"
    tokio = { version = "1", features = ["full"]}
  2. Build the project with cargo build and fetch and compile the dependencies.

  3. Add the following line to the includes in the source code of your app, such as main.rs:

    use stargate_grpc::*;

This set-up will make all the Stargate gRPC functionality available.

The next sections explain the parts of a script to use the Stargate functionality. A full working script is included below.

Rust connecting

Authentication

This example assumes that you’re running Stargate locally with the default credentials of cassandra/cassandra. For more information regarding authentication please see the Stargate authentication and authorization docs.

You’ll need to generate a token to insert into the client connection code:

curl -L -X POST 'http://$ASTRA_CLUSTER_ID-$ASTRA_REGION.apps.astra.datastax.com:8081/v1/auth' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "username": "cassandra",
    "password": "cassandra"
}'

Set up client

The main structure that provides the interface to Stargate is StargateClient. The simplest way to obtain an instance is to use the provided builder:

use stargate_grpc::*;
use std::str::FromStr;

// Set the Stargate OSS configuration for a locally running docker container:
let sg_uri = "http://localhost:8090/";
let auth_token = "06251024-5aeb-4200-a132-5336e73e5b6e";

// For Stargate OSS: create a client
let mut client = StargateClient::builder()
.uri(sg_uri)?
.auth_token(AuthToken::from_str(auth_token)?)
.connect()
.await?;

println!("created client {:?}", client);

Rust querying

Use QueryBuilder to create a query, bind query values and pass query parameters. The query is followed by the execute commands that actually run the command and return the results.

  • Rust query builder command (/v2)

  • Rust execute command

// For Stargate OSS: SELECT the data to read from the table
// Select/query some data from the keyspace.table
let query = Query::builder()
  // Set the keyspace for the the query
  .keyspace("test")
  // Set consistency level
  .consistency(Consistency::One)
  .query("SELECT firstname, lastname FROM test.users;")
  // Build the query
  .build();

println!("select executed");
use std::convert::TryInto;

// Send the query and wait for gRPC response
let response = client.execute_query(query).await?;

// Convert the response into a ResultSet
let result_set: ResultSet = response.try_into()?;

It is also possible to use a bind statement to insert values:

.query("SELECT login, emails FROM users WHERE id = :id")
.bind_value("id", 1000)

Data definition language (DDL) queries are supported in the same manner:

// For Stargate OSS only: create a keyspace
let create_keyspace = Query::builder()
    .query("CREATE KEYSPACE IF NOT EXISTS test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1};")
    .build();
client.execute_query(create_keyspace).await?;

println!("created keyspace");

// For Stargate OSS: create a table
let create_table = Query::builder()
    .query(
        "CREATE TABLE IF NOT EXISTS test.users \
            (firstname text, lastname text, PRIMARY KEY (firstname, lastname));",
    )
    .build();
 client.execute_query(create_table).await?;

 println!("created table");

In general, users will create a keyspace and table first.

The ExecuteQuery function can be used to execute a single query.

If you need to group several commands together as a batch statement, the client also provides an ExecuteBatch() function to execute a batch query:

// For Stargate OSS: INSERT two rows/records
//  Two queries will be run in a batch statement
let batch = Batch::builder()
    .keyspace("test")                   // set the keyspace the query applies to
    .consistency(Consistency::One)      // set consistency level
    .query("INSERT INTO test.users (firstname, lastname) VALUES ('Jane', 'Doe');")
    .query("INSERT INTO test.users (firstname, lastname) VALUES ('Serge', 'Provencio');")
    .build();
client.execute_batch(batch).await?;

println!("insert data");

This example inserts two values into the keyspace table test.users. Only INSERT, UPDATE, and DELETE operations can be used in a batch query.

Rust processing result set

The result set comes back as a collection of rows. A row can be easily unpacked:

// This for loop to get the results
   for row in result_set.rows {
       let (firstname, lastname): (String, String) = row.try_into()?;
       println!("{} {}", firstname, lastname);
   }

Rust full sample script

To put all the pieces together, here is a sample script that combines all the pieces shown above:

  • Sample script

  • Result

use stargate_grpc::*;
use std::str::FromStr;
use std::error::Error;
use std::convert::TryInto;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {

    // For Stargate OSS: create a client
    let mut client = StargateClient::builder()

    // For Stargate OSS running locally in docker container, set connect information:
    .uri("http://localhost:8090/")?                           // replace with a proper address
    .auth_token(AuthToken::from_str("721e9c04-e121-4bf4-b9a6-887ebeae2bc5")?)    // replace with a proper token
    .connect()
    .await?;

    println!("created client {:?}", client);

    // For Stargate OSS only: create a keyspace
    let create_keyspace = Query::builder()
        .query("CREATE KEYSPACE IF NOT EXISTS test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1};")
        .build();
    client.execute_query(create_keyspace).await?;

    println!("created keyspace");

    // For Stargate OSS: create a table
    let create_table = Query::builder()
        // .keyspace("test")
        .query(
            "CREATE TABLE IF NOT EXISTS test.users \
                (firstname text, lastname text, PRIMARY KEY (firstname, lastname));",
        )
        .build();
     client.execute_query(create_table).await?;

     println!("created table");

    // For Stargate OSS: INSERT two rows/records
	//  Two queries will be run in a batch statement
    let batch = Batch::builder()
        .keyspace("test")                   // set the keyspace the query applies to
        .consistency(Consistency::One)      // set consistency level
        .query("INSERT INTO test.users (firstname, lastname) VALUES ('Lorina', 'Poland');")
        .query("INSERT INTO test.users (firstname, lastname) VALUES ('Doug', 'Wettlaufer');")
        .build();
    client.execute_batch(batch).await?;

    println!("insert data");

    // For Stargate OSS: SELECT the data to read from the table
    // Select/query some data from the keyspace.table
    let query = Query::builder()
        .keyspace("test")
        .consistency(Consistency::One)
        .query("SELECT firstname, lastname FROM test.users;")
        .build();

     println!("select executed");

    // Get the results from the execute query statement and convert into a ResultSet
    let response = client.execute_query(query).await?;
    let result_set: ResultSet = response.try_into()?;

    // This for loop to get the results
    for row in result_set.rows {
        let (firstname, lastname): (String, String) = row.try_into()?;
        println!("{} {}", firstname, lastname);
    }
    println!("everything worked!");
    Ok(())
}
created client StargateClient { inner: Grpc { inner: InterceptedService { inner: Channel, f: stargate_grpc::client::AuthToken } } }
created keyspace
created table
insert data
select executed
Jane Doe
Serge Provencio
everything worked!

Rust developing

Building

Install Rust toolchain:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Run build in the root directory of the project:
git clone https://github.com/stargate/stargate-grpc-rust-client stargate-grpc
cd stargate-grpc
cargo build

Running the examples

For your convenience, this project contains a bunch of examples located in the examples directory, which demonstrate connecting, creating schemas, inserting data and querying. You’ll need a working instance of a Stargate cluster to run the examples. Refer to the official Stargate Installation documentation for more details on how to setup Stargate.

Each example program accepts an URL of the Stargate coordinator, the authentication token and the keyspace name:

cargo run --example <example> [-- [--keyspace <keyspace>] [--token <token>] [--tls] [<url>]]

The authentication token value can be also defined in the SG_TOKEN environment variable.

Run examples

Run the keyspace example to test the connection and create the test keyspace with the default keyspace name of stargate_examples:

  • Run test

  • Result

cargo run --example keyspace
Connected to http://127.0.0.2:8090
Created keyspace stargate_examples

Run the query example to create a keyspace and table, insert some data, and select data to check the insertion:

  • Run test

  • Result

cargo run --example query
Finished dev [unoptimized + debuginfo] target(s) in 0.04s
Running `target/debug/examples/basic`
Connected to http://127.0.0.2:8090
Created schema
Inserted data. Now querying.
All rows:
2 user_2 ["user_2@example.net", "user_2@mail.example.net"]
3 user_3 ["user_3@example.net", "user_3@mail.example.net"]
7 user_7 ["user_7@example.net", "user_7@mail.example.net"]
9 user_9 ["user_9@example.net", "user_9@mail.example.net"]
4 user_4 ["user_4@example.net", "user_4@mail.example.net"]
0 user_0 ["user_0@example.net", "user_0@mail.example.net"]
8 user_8 ["user_8@example.net", "user_8@mail.example.net"]
5 user_5 ["user_5@example.net", "user_5@mail.example.net"]
6 user_6 ["user_6@example.net", "user_6@mail.example.net"]
1 user_1 ["user_1@example.net", "user_1@mail.example.net"]
Row with id = 1:
1 user_1 ["user_1@example.net", "user_1@mail.example.net"]

The Stargate gRPC Rust Client repository is located at https://github.com/stargate/stargate-grpc-rust-client.

Develop with gRPC gRPC Go client

General Inquiries: +1 (650) 389-6000 info@datastax.com

© DataStax | Privacy policy | Terms of use

DataStax, Titan, and TitanDB are registered trademarks of DataStax, Inc. and its subsidiaries in the United States and/or other countries.

Apache, Apache Cassandra, Cassandra, Apache Tomcat, Tomcat, Apache Lucene, Apache Solr, Apache Hadoop, Hadoop, Apache Pulsar, Pulsar, Apache Spark, Spark, Apache TinkerPop, TinkerPop, Apache Kafka and Kafka are either registered trademarks or trademarks of the Apache Software Foundation or its subsidiaries in Canada, the United States and/or other countries.

Kubernetes is the registered trademark of the Linux Foundation.

landing_page landingpage