How-To: Save and get state

Use key value pairs to persist a state

Introduction

State management is one of the most common needs of any application: new or legacy, monolith or microservice. Dealing with different databases libraries, testing them, handling retries and faults can be time consuming and hard.

Dapr provides state management capabilities that include consistency and concurrency options. In this guide we’ll start of with the basics: Using the key/value state API to allow an application to save, get and delete state.

Step 1: Setup a state store

A state store component represents a resource that Dapr uses to communicate with a database. For the purpose of this how to we’ll use a Redis state store, but any state store from the supported list will work.


When using Dapr init in Standalone mode, the Dapr CLI automatically provisions a state store (Redis) and creates the relevant YAML in a components directory, which for Linux/MacOS is $HOME/.dapr/components and for Windows is %USERPROFILE%\.dapr\components

To change the state store being used, replace the YAML under /components with the file of your choice.


See the instructions here on how to setup different state stores on Kubernetes.

Step 2: Save state

The following example shows how to save two key/value pairs in a single call using the state management API.


Begin by ensuring a Dapr sidecar is running:

dapr --app-id myapp --port 3500 run

Then in a separate terminal run:

curl -X POST -H "Content-Type: application/json" -d '[{ "key": "key1", "value": "value1"}, { "key": "key2", "value": "value2"}]' http://localhost:3500/v1.0/state/statestore

Begin by ensuring a Dapr sidecar is running:

dapr --app-id myapp --port 3500 run

Then in a separate terminal run:

Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '[{ "key": "key1", "value": "value1"}, { "key": "key2", "value": "value2"}]' -Uri 'http://localhost:3500/v1.0/state/statestore'

Make sure to install the Dapr Python SDK with pip3 install dapr. Then create a file named state.py with:

from dapr.clients import DaprClient
from dapr.clients.grpc._state import StateItem

with DaprClient() as d:
    d.save_states(store_name="statestore",
                  states=[
                      StateItem(key="key1", value="value1"),
                      StateItem(key="key2", value="value2")
                      ])

Run with dapr run --app-id myapp run python state.py

Step 3: Get state

The following example shows how to get an item by using a key with the state management API:


With the same dapr instance running from above run:

curl http://localhost:3500/v1.0/state/statestore/key1

With the same dapr instance running from above run:

Invoke-RestMethod -Uri 'http://localhost:3500/v1.0/state/statestore/key1'

Add the following code to state.py from above and run again:

    data = d.get_state(store_name="statestore",
                       key="key1",
                       state_metadata={"metakey": "metavalue"}).data
    print(f"Got value: {data}")

Step 4: Delete state

The following example shows how to delete an item by using a key with the state management API:


With the same dapr instance running from above run:

curl -X DELETE 'http://localhost:3500/v1.0/state/statestore/key1'

Try getting state again and note that no value is returned.


With the same dapr instance running from above run:

Invoke-RestMethod -Method Delete -Uri 'http://localhost:3500/v1.0/state/statestore/key1'

Try getting state again and note that no value is returned.


Add the following code to state.py from above and run again:

    d.delete_state(store_name="statestore"",
                   key="key1",
                   state_metadata={"metakey": "metavalue"})
    data = d.get_state(store_name="statestore",
                       key="key1",
                       state_metadata={"metakey": "metavalue"}).data
    print(f"Got value after delete: {data}")