Dapr Rust SDK

repository·main·Indexed 42 days ago

https://github.com/dapr/rust-sdk

An Alpha-stage client library for building distributed applications using the Dapr runtime. It provides Rust-native interfaces for Dapr building blocks including Workflows, Actors, State Management, Pub/Sub, Secrets, and Service Invocation, handling sidecar communication via gRPC.

Tokens
33.4K
Snippets
89
Records
162
Agent score
51%

What's inside Dapr Rust SDK

  1. Explore Dapr Rust SDK usage examples

    main

    The examples directory contains various implementations demonstrating the capabilities of the Dapr Rust SDK. You can use these as templates for your own applications. Key functional areas covered include:

    • Actors: Hosting actors and making actor client calls.
    • Authentication: Implementing inbound authentication on an app-callback server using AppApiTokenLayer.
    • Bindings: Using Dapr input and output bindings.
    • State Management: Saving, getting, and deleting state, as well as performing state queries against query-capable stores.
    • Configuration: Reading and subscribing to Dapr configuration values.
    • Cryptography: Performing Dapr cryptography operations.
    • Service Invocation: Invoking services over gRPC or through Dapr gRPC proxying.
    • Pub/Sub: Publishing and subscribing to events.
    • Secrets: Retrieving secrets (including bulk retrieval).
    • Workflows: Registering, running, waiting for, purging, and managing parallel or sustained workflows, including history propagation and task execution IDs.
    • Jobs: Scheduling Dapr jobs and configuring failure policies.
    • Conversation: Interacting with Dapr conversation components (alpha1/alpha2).
  2. Implement Input Bindings using AppCallback

    main

    To implement input bindings in a Rust application using the Dapr SDK, you must implement the AppCallback server trait. This allows the Dapr runtime to communicate with your application when binding events occur.

    Specifically, you must implement these two methods:

    1. list_input_bindings: The Dapr runtime calls this method to retrieve the list of bindings the application is currently subscribed to.
    2. on_binding_event: This method defines the logic for how your application handles an incoming input binding event.

    Note: Ensure you are using the latest version of the proto bindings for compatibility.

  3. Implement Pub/Sub subscription using AppCallback

    main

    To subscribe to events in a Dapr Rust application, you must implement the AppCallback server. This allows the Dapr runtime to communicate with your application regarding topic subscriptions and incoming events.

    Two specific methods must be implemented:

    1. list_topic_subscriptions: The Dapr runtime calls this to retrieve the list of topics your application is currently subscribed to.
    2. on_topic_event: This method defines the logic for how your application handles an event received on a specific topic.

    Note: Ensure you are using the latest version of the proto bindings for compatibility.

  4. Run the Jobs Example

    main

    The Jobs Example demonstrates Dapr's job scheduling capabilities. To run the demonstration, you must first build the examples and then use the Dapr CLI to run the multi-app template.

    1. Build the examples:
    cargo build --examples
    1. Run the multi-app template: Use the Dapr CLI to run the configuration defined in the current directory:
    dapr run -f .
    1. Stop the process: Press ctrl + c to terminate the running example.
    cargo build --examples
    dapr run -f .
  5. Run the gRPC Service Invocation Example

    main

    This example demonstrates how to perform service-to-service invocation using gRPC within the Dapr Rust SDK. It involves a server application (invoke-grpc-server) and a client application (invoke-grpc-client).

    Prerequisites

    Ensure a local Redis state store is running by checking your containers:

    docker ps

    Build the Example

    Build the example binaries using cargo:

    cargo build --examples

    Run the Multi-app Example

    You can run both the client and server simultaneously using a Dapr configuration file:

    dapr run -f .

    Manual Execution

    If you prefer to run the components individually, use the following commands:

    1. Start the Server Run the server with the grpc protocol on port 50051:

    dapr run --app-id=invoke-grpc-server --app-protocol grpc --app-port 50051 -- cargo run --example invoke-grpc-server

    2. Start the Client Run the client to invoke the server:

    dapr run --app-id=invoke-grpc-client -- cargo run --example invoke-grpc-client
  6. Run the Jobs with Failure Policy example

    main

    This example demonstrates Dapr's job scheduling capabilities combined with a failure policy. To run the demonstration, you must first build the examples and then use the Dapr multi-app run template to orchestrate the components.

    Prerequisites

    Ensure you have cargo and the dapr CLI installed and available in your path.

    # 1. Build the examples
    cargo build --examples
    
    # 2. Run the multi-app template
    dapr run -f .
    
    # 3. Stop the process using Ctrl+C
  7. Run the Query State Rust Examples

    main

    After setting up the MongoDB state store and populating it with data, follow these steps to run the Rust query examples.

    1. Build the examples:
      cargo build --examples
    
    2. **Execute Query 1 (Equality and Sort)**:
     This query filters for records where `state` is `CA` and sorts them by `person.id` in descending order.
     **Query JSON**:
     ```json
     {
         "filter": {
             "EQ": { "state": "CA" }
         },
         "sort": [
             {
                 "key": "person.id",
                 "order": "DESC"
             }
         ]
     }

    Command:

    dapr run --app-id=rustapp --dapr-grpc-port 50001 --resources-path statestore/ -- cargo run --example query-state-1
    1. Execute Query 2 (In-list Filter): This query filters for records where person.org is either Dev Ops or Hardware. Query JSON:
      {
          "filter": {
              "IN": { "person.org": [ "Dev Ops", "Hardware" ] }
          }
      }
      Command:
      dapr run --app-id=rustapp --dapr-grpc-port 50001 --resources-path statestore/ -- cargo run --example query-state-2
    cargo build --examples
    
    # Run first example
    dapr run --app-id=rustapp --dapr-grpc-port 50001 --resources-path statestore/ -- cargo run --example query-state-1
    
    # Run second example
    dapr run --app-id=rustapp --dapr-grpc-port 50001 --resources-path statestore/ -- cargo run --example query-state-2
  8. Configure Outbound and Inbound Authentication

    main

    Outbound Authentication

    To authenticate requests sent by your application to the Dapr sidecar, set the DAPR_API_TOKEN environment variable or use ClientOptions::with_api_token. The client will automatically attach the dapr-api-token metadata header to every request.

    Inbound Authentication

    To protect your application's callback gRPC server, use the AppApiTokenLayer with your tonic server. This layer enforces the APP_API_TOKEN environment variable. If the environment variable is unset, the layer acts as a no-op.

    use dapr::appcallback::AppCallbackService;
    use dapr::client::AppApiTokenLayer;
    use dapr::dapr::proto::runtime::v1::app_callback_server::AppCallbackServer;
    use tonic::transport::Server;
    
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let addr = "127.0.0.1:50051".parse()?;
        Server::builder()
            .layer(AppApiTokenLayer::from_env())
            .add_service(AppCallbackServer::new(AppCallbackService::new()))
            .serve(addr)
            .await?;
        Ok(())
    }
  9. Run the Input and Output Bindings Example

    main

    Follow these steps to build and run the bindings example using Kafka and Dapr.

    1. Build the examples:

      cargo build --examples
    2. Start a Kafka instance: Use Docker to run a Kafka container on port 9092:

      docker run -p 9092:9092 apache/kafka:3.7.1
    3. Run with Dapr: Use the provided multi-app run template (dapr.yaml) to start the application:

      dapr run -f .
    # Build
    cargo build --examples
    
    # Run Kafka
    docker run -p 9092:9092 apache/kafka:3.7.1
    
    # Run Dapr
    dapr run -f .
  10. Implement inbound authentication with AppApiTokenLayer

    main

    You can secure your Dapr app-callback server (using tonic for gRPC) by using dapr::client::AppApiTokenLayer.

    When the APP_API_TOKEN environment variable is set, this layer intercepts incoming gRPC requests and rejects any that do not contain a matching dapr-api-token metadata header. If APP_API_TOKEN is unset, the layer acts as a no-op and performs no authentication.

    To use this, you must configure the matching token on the Dapr sidecar using the standard Dapr appApiToken mechanism.

    // Example usage pattern: installing the layer on a tonic server
    // (Note: Actual implementation details depend on your tonic server setup)
    // AppApiTokenLayer::from_env()
  11. Run the Configuration example

    main

    This guide demonstrates how to use the Dapr Rust SDK to interact with the Configuration API, including reading configuration items and subscribing to configuration changes using a Redis state store as the backend.

    Prerequisites

    Ensure a local Redis state store is running by checking your containers:

    docker ps

    Steps to Execute

    1. Build the examples:

      cargo build --examples
    2. Initialize test data in Redis: Insert a key hello with the value world into the Redis instance:

      docker exec dapr_redis redis-cli MSET hello "world"
    3. Run the configuration application via Dapr: Use dapr run to launch the example app. Note the --resources-path points to your Dapr component definitions:

      dapr run --app-id=rustapp --resources-path ../components --dapr-grpc-port 50001 -- cargo run --example configuration
    4. Trigger a configuration change: To test the subscription mechanism, update the value of hello in Redis:

      docker exec dapr_redis redis-cli MSET hello "world2"

    Expected Output

    If successful, the application will output the initial value, detect the change via the subscription, and then show the unsubscription message:

    Configuration value: ConfigurationItem { value: "world", version: "", metadata: {} }
    App subscribed to config changes with subscription id: "d383169a-0893-4c64-adde-fc3145b56d07" 
    Configuration value: {"hello": ConfigurationItem { value: "world2", version: "", metadata: {} }}
    App unsubscribed from config changes
    dapr run --app-id=rustapp --resources-path ../components --dapr-grpc-port 50001 -- cargo run --example configuration