docs/daprdocs/content/en/getting-started/quickstarts/statemanagement-quickstart.md

1306 lines
42 KiB
Markdown

---
type: docs
title: "Quickstart: State Management"
linkTitle: "State Management"
weight: 74
description: "Get started with Dapr's State Management building block"
---
Let's take a look at Dapr's [State Management building block]({{< ref state-management >}}). In this Quickstart, you will save, get, and delete state using a Redis state store by either:
- [Running all applications simultaneously with the Multi-App Run template file]({{< ref "#run-using-multi-app-run" >}}), or
- [Running a single application at a time]({{< ref "#run-one-application-at-a-time" >}})
<img src="/images/state-management-quickstart.png" width=1000 style="padding-bottom:15px;">
While this sample uses Redis, you can swap it out for any one of the [supported state stores]({{< ref supported-state-stores.md >}}).
## Run using Multi-App Run
Select your preferred language-specific Dapr SDK before proceeding with the Quickstart.
{{< tabs "Python" "JavaScript" ".NET" "Java" "Go" >}}
<!-- Python -->
{{% codetab %}}
### Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [Python 3.7+ installed](https://www.python.org/downloads/).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 1: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/state_management/python/sdk).
```bash
git clone https://github.com/dapr/quickstarts.git
```
### Step 2: Manipulate service state
In a terminal window, navigate to the `order-processor` directory.
```bash
cd state_management/python/sdk/order-processor
```
Install the dependencies:
```bash
pip3 install -r requirements.txt
```
Run the `order-processor` service alongside a Dapr sidecar using [Multi-App Run]({{< ref multi-app-dapr-run >}}).
```bash
dapr run -f .
```
> **Note**: Since Python3.exe is not defined in Windows, you may need to change `python3` to `python` in the [`dapr.yaml`]({{< ref "#dapryaml-multi-app-run-template-file" >}}) file before running `dapr run -f .`
The `order-processor` service writes, reads, and deletes an `orderId` key/value pair to the `statestore` instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). As soon as the service starts, it performs a loop.
```python
with DaprClient() as client:
# Save state into the state store
client.save_state(DAPR_STORE_NAME, orderId, str(order))
logging.info('Saving Order: %s', order)
# Get state from the state store
result = client.get_state(DAPR_STORE_NAME, orderId)
logging.info('Result after get: ' + str(result.data))
# Delete state from the state store
client.delete_state(store_name=DAPR_STORE_NAME, key=orderId)
logging.info('Deleting Order: %s', order)
```
### Step 3: View the order-processor outputs
Notice, as specified in the code above, the code saves application state in the Dapr state store, reads it, then deletes it.
Order-processor output:
```
== APP == INFO:root:Saving Order: {'orderId': '1'}
== APP == INFO:root:Result after get: b"{'orderId': '1'}"
== APP == INFO:root:Deleting Order: {'orderId': '1'}
== APP == INFO:root:Saving Order: {'orderId': '2'}
== APP == INFO:root:Result after get: b"{'orderId': '2'}"
== APP == INFO:root:Deleting Order: {'orderId': '2'}
== APP == INFO:root:Saving Order: {'orderId': '3'}
== APP == INFO:root:Result after get: b"{'orderId': '3'}"
== APP == INFO:root:Deleting Order: {'orderId': '3'}
== APP == INFO:root:Saving Order: {'orderId': '4'}
== APP == INFO:root:Result after get: b"{'orderId': '4'}"
== APP == INFO:root:Deleting Order: {'orderId': '4'}
```
##### `dapr.yaml` Multi-App Run template file
When you run `dapr init`, Dapr creates a default [Multi-App Run template file]({{< ref multi-app-dapr-run >}}) named `dapr.yaml`. Running `dapr run -f` starts all applications in your project. In this sample, the `dapr.yaml` file contains the following:
```yml
version: 1
common:
resourcesPath: ../../resources/
apps:
- appID: order-processor
appDirPath: ./order-processor/
command: ["python3" , "app.py"]
```
##### `statestore.yaml` component file
When you run `dapr init`, Dapr also creates a default Redis `statestore.yaml` and runs a Redis container on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out the [state store](/reference/components-reference/supported-state-stores/) without making code changes.
The Redis `statestore.yaml` file included for this quickstart contains the following:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
```
In the YAML file:
- `metadata/name` is how your application talks to the component (called `DAPR_STORE_NAME` in the code sample).
- `spec/metadata` defines the connection to the Redis instance used by the component.
{{% /codetab %}}
<!-- JavaScript -->
{{% codetab %}}
### Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [Latest Node.js installed](https://nodejs.org/download/).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 1: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/state_management/javascript/sdk).
```bash
git clone https://github.com/dapr/quickstarts.git
```
### Step 2: Manipulate service state
In a terminal window, navigate to the `order-processor` directory.
```bash
cd state_management/javascript/sdk/order-processor
```
Install the dependencies:
```bash
npm install
```
Run the `order-processor` service alongside a Dapr sidecar.
```bash
dapr run -f .
```
The `order-processor` service writes, reads, and deletes an `orderId` key/value pair to the `statestore` instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). As soon as the service starts, it performs a loop.
```js
const client = new DaprClient()
// Save state into a state store
await client.state.save(DAPR_STATE_STORE_NAME, order)
console.log("Saving Order: ", order)
// Get state from a state store
const savedOrder = await client.state.get(DAPR_STATE_STORE_NAME, order.orderId)
console.log("Getting Order: ", savedOrder)
// Delete state from the state store
await client.state.delete(DAPR_STATE_STORE_NAME, order.orderId)
console.log("Deleting Order: ", order)
```
### Step 3: View the order-processor outputs
Notice, as specified in the code above, the code saves application state in the Dapr state store, reads it, then deletes it.
Order-processor output:
```
== APP == > order-processor@1.0.0 start
== APP == > node index.js
== APP == Saving Order: { orderId: 1 }
== APP == Saving Order: { orderId: 2 }
== APP == Saving Order: { orderId: 3 }
== APP == Saving Order: { orderId: 4 }
== APP == Saving Order: { orderId: 5 }
== APP == Getting Order: { orderId: 1 }
== APP == Deleting Order: { orderId: 1 }
== APP == Getting Order: { orderId: 2 }
== APP == Deleting Order: { orderId: 2 }
== APP == Getting Order: { orderId: 3 }
== APP == Deleting Order: { orderId: 3 }
== APP == Getting Order: { orderId: 4 }
== APP == Deleting Order: { orderId: 4 }
== APP == Getting Order: { orderId: 5 }
== APP == Deleting Order: { orderId: 5 }
```
##### `dapr.yaml` Multi-App Run template file
When you run `dapr init`, Dapr creates a default Multi-App Run template file named `dapr.yaml`. Running `dapr run -f` starts all applications in your project. In this sample, the `dapr.yaml` file contains the following:
```yml
version: 1
common:
resourcesPath: ../../resources/
apps:
- appID: order-processor
appDirPath: ./order-processor/
command: ["npm", "run", "start"]
```
##### `statestore.yaml` component file
When you run `dapr init`, Dapr creates a default Redis `statestore.yaml` and runs a Redis container on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out the [state store](/reference/components-reference/supported-state-stores/) without making code changes.
The Redis `statestore.yaml` file included for this quickstart contains the following:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
```
In the YAML file:
- `metadata/name` is how your application talks to the component (called `DAPR_STORE_NAME` in the code sample).
- `spec/metadata` defines the connection to the Redis instance used by the component.
{{% /codetab %}}
<!-- .NET -->
{{% codetab %}}
### Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
- [.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0), [.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0) or [.NET 9](https://dotnet.microsoft.com/download/dotnet/9.0) installed
**NOTE:** .NET 6 is the minimally supported version of .NET for the Dapr .NET SDK packages in this release. Only .NET 8 and .NET 9
will be supported in Dapr v1.16 and later releases.
### Step 1: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/state_management/csharp/sdk).
```bash
git clone https://github.com/dapr/quickstarts.git
```
### Step 2: Manipulate service state
In a terminal window, navigate to the `order-processor` directory.
```bash
cd state_management/csharp/sdk/order-processor
```
Install the dependencies:
```bash
dotnet restore
dotnet build
```
Run the `order-processor` service alongside a Dapr sidecar.
```bash
dapr run -f .
```
The `order-processor` service writes, reads, and deletes an `orderId` key/value pair to the `statestore` instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). As soon as the service starts, it performs a loop.
```cs
var client = new DaprClientBuilder().Build();
// Save state into the state store
await client.SaveStateAsync(DAPR_STORE_NAME, orderId.ToString(), order.ToString());
Console.WriteLine("Saving Order: " + order);
// Get state from the state store
var result = await client.GetStateAsync<string>(DAPR_STORE_NAME, orderId.ToString());
Console.WriteLine("Getting Order: " + result);
// Delete state from the state store
await client.DeleteStateAsync(DAPR_STORE_NAME, orderId.ToString());
Console.WriteLine("Deleting Order: " + order);
```
### Step 3: View the order-processor outputs
Notice, as specified in the code above, the code saves application state in the Dapr state store, reads it, then deletes it.
Order-processor output:
```
== APP == Saving Order: Order { orderId = 1 }
== APP == Getting Order: Order { orderId = 1 }
== APP == Deleting Order: Order { orderId = 1 }
== APP == Saving Order: Order { orderId = 2 }
== APP == Getting Order: Order { orderId = 2 }
== APP == Deleting Order: Order { orderId = 2 }
== APP == Saving Order: Order { orderId = 3 }
== APP == Getting Order: Order { orderId = 3 }
== APP == Deleting Order: Order { orderId = 3 }
== APP == Saving Order: Order { orderId = 4 }
== APP == Getting Order: Order { orderId = 4 }
== APP == Deleting Order: Order { orderId = 4 }
== APP == Saving Order: Order { orderId = 5 }
== APP == Getting Order: Order { orderId = 5 }
== APP == Deleting Order: Order { orderId = 5 }
```
##### `dapr.yaml` Multi-App Run template file
When you run `dapr init`, Dapr creates a default Multi-App Run template file named `dapr.yaml`. Running `dapr run -f` starts all applications in your project. In this sample, the `dapr.yaml` file contains the following:
```yml
version: 1
common:
resourcesPath: ../../../resources/
apps:
- appID: order-processor
appDirPath: ./order-processor/
command: ["dotnet", "run"]
```
##### `statestore.yaml` component file
When you run `dapr init`, Dapr creates a default Redis `statestore.yaml` and runs a Redis container on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out the [state store](/reference/components-reference/supported-state-stores/) without making code changes.
The Redis `statestore.yaml` file included for this quickstart contains the following:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
```
In the YAML file:
- `metadata/name` is how your application talks to the component (called `DAPR_STORE_NAME` in the code sample).
- `spec/metadata` defines the connection to the Redis instance used by the component.
{{% /codetab %}}
<!-- Java -->
{{% codetab %}}
### Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- Java JDK 17 (or greater):
- [Oracle JDK](https://www.oracle.com/java/technologies/downloads), or
- OpenJDK
- [Apache Maven](https://maven.apache.org/install.html), version 3.x.
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 1: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/state_management/java/sdk).
```bash
git clone https://github.com/dapr/quickstarts.git
```
### Step 2: Manipulate service state
In a terminal window, navigate to the `order-processor` directory.
```bash
cd state_management/java/sdk/order-processor
```
Install the dependencies:
```bash
mvn clean install
```
Run the `order-processor` service alongside a Dapr sidecar.
```bash
dapr run -f .
```
The `order-processor` service writes, reads, and deletes an `orderId` key/value pair to the `statestore` instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). As soon as the service starts, it performs a loop.
```java
try (DaprClient client = new DaprClientBuilder().build()) {
for (int i = 1; i <= 10; i++) {
int orderId = i;
Order order = new Order();
order.setOrderId(orderId);
// Save state into the state store
client.saveState(DAPR_STATE_STORE, String.valueOf(orderId), order).block();
LOGGER.info("Saving Order: " + order.getOrderId());
// Get state from the state store
State<Order> response = client.getState(DAPR_STATE_STORE, String.valueOf(orderId), Order.class).block();
LOGGER.info("Getting Order: " + response.getValue().getOrderId());
// Delete state from the state store
client.deleteState(DAPR_STATE_STORE, String.valueOf(orderId)).block();
LOGGER.info("Deleting Order: " + orderId);
TimeUnit.MILLISECONDS.sleep(1000);
}
```
### Step 3: View the order-processor outputs
Notice, as specified in the code above, the code saves application state in the Dapr state store, reads it, then deletes it.
Order-processor output:
```
== APP == INFO:root:Saving Order: {'orderId': '1'}
== APP == INFO:root:Result after get: b"{'orderId': '1'}"
== APP == INFO:root:Deleting Order: {'orderId': '1'}
== APP == INFO:root:Saving Order: {'orderId': '2'}
== APP == INFO:root:Result after get: b"{'orderId': '2'}"
== APP == INFO:root:Deleting Order: {'orderId': '2'}
== APP == INFO:root:Saving Order: {'orderId': '3'}
== APP == INFO:root:Result after get: b"{'orderId': '3'}"
== APP == INFO:root:Deleting Order: {'orderId': '3'}
== APP == INFO:root:Saving Order: {'orderId': '4'}
== APP == INFO:root:Result after get: b"{'orderId': '4'}"
== APP == INFO:root:Deleting Order: {'orderId': '4'}
```
##### `dapr.yaml` Multi-App Run template file
When you run `dapr init`, Dapr creates a default Multi-App Run template file named `dapr.yaml`. Running `dapr run -f` starts all applications in your project. In this sample, the `dapr.yaml` file contains the following:
```yml
version: 1
common:
resourcesPath: ../../resources/
apps:
- appID: order-processor
appDirPath: ./order-processor/
command: ["java", "-jar", "target/OrderProcessingService-0.0.1-SNAPSHOT.jar"]
```
##### `statestore.yaml` component file
When you run `dapr init`, Dapr creates a default Redis `statestore.yaml` and runs a Redis container on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out the [state store](/reference/components-reference/supported-state-stores/) without making code changes.
The Redis `statestore.yaml` file included for this Quickstart contains the following:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
```
In the YAML file:
- `metadata/name` is how your application talks to the component (called `DAPR_STORE_NAME` in the code sample).
- `spec/metadata` defines the connection to the Redis instance used by the component.
{{% /codetab %}}
<!-- Go -->
{{% codetab %}}
### Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [Latest version of Go](https://go.dev/dl/).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 1: Set up the environment
Clone the [sample provided in the Quickstarts repo](hhttps://github.com/dapr/quickstarts/tree/master/state_management/go/sdk).
```bash
git clone https://github.com/dapr/quickstarts.git
```
### Step 2: Manipulate service state
In a terminal window, navigate to the `order-processor` directory.
```bash
cd state_management/go/sdk/order-processor
```
Install the dependencies:
```bash
go build .
```
Run the `order-processor` service alongside a Dapr sidecar.
```bash
dapr run -f .
```
The `order-processor` service writes, reads, and deletes an `orderId` key/value pair to the `statestore` instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). As soon as the service starts, it performs a loop.
```go
client, err := dapr.NewClient()
// Save state into the state store
_ = client.SaveState(ctx, STATE_STORE_NAME, strconv.Itoa(orderId), []byte(order))
log.Print("Saving Order: " + string(order))
// Get state from the state store
result, _ := client.GetState(ctx, STATE_STORE_NAME, strconv.Itoa(orderId))
fmt.Println("Getting Order: " + string(result.Value))
// Delete state from the state store
_ = client.DeleteState(ctx, STATE_STORE_NAME, strconv.Itoa(orderId))
log.Print("Deleting Order: " + string(order))
```
### Step 3: View the order-processor outputs
Notice, as specified in the code above, the code saves application state in the Dapr state store, reads it, then deletes it.
Order-processor output:
```
== APP == dapr client initializing for: 127.0.0.1:53689
== APP == 2022/04/01 09:16:03 Saving Order: {"orderId":1}
== APP == Getting Order: {"orderId":1}
== APP == 2022/04/01 09:16:03 Deleting Order: {"orderId":1}
== APP == 2022/04/01 09:16:03 Saving Order: {"orderId":2}
== APP == Getting Order: {"orderId":2}
== APP == 2022/04/01 09:16:03 Deleting Order: {"orderId":2}
== APP == 2022/04/01 09:16:03 Saving Order: {"orderId":3}
== APP == Getting Order: {"orderId":3}
== APP == 2022/04/01 09:16:03 Deleting Order: {"orderId":3}
== APP == 2022/04/01 09:16:03 Saving Order: {"orderId":4}
== APP == Getting Order: {"orderId":4}
== APP == 2022/04/01 09:16:03 Deleting Order: {"orderId":4}
== APP == 2022/04/01 09:16:03 Saving Order: {"orderId":5}
== APP == Getting Order: {"orderId":5}
== APP == 2022/04/01 09:16:03 Deleting Order: {"orderId":5}
```
##### `dapr.yaml` Multi-App Run template file
When you run `dapr init`, Dapr creates a default Multi-App Run template file named `dapr.yaml`. Running `dapr run -f` starts all applications in your project. In this sample, the `dapr.yaml` file contains the following:
```yml
version: 1
common:
resourcesPath: ../../resources/
apps:
- appID: order-processor
appDirPath: ./order-processor/
command: ["go", "run", "."]
```
##### `statestore.yaml` component file
When you run `dapr init`, Dapr creates a default Redis `statestore.yaml` and runs a Redis container on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out the [state store](/reference/components-reference/supported-state-stores/) without making code changes.
The Redis `statestore.yaml` file included for this Quickstart contains the following:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
```
In the YAML file:
- `metadata/name` is how your application talks to the component (called `DAPR_STORE_NAME` in the code sample).
- `spec/metadata` defines the connection to the Redis instance used by the component.
{{% /codetab %}}
{{< /tabs >}}
## Run one application at a time
Select your preferred language-specific Dapr SDK before proceeding with the Quickstart.
{{< tabs "Python" "JavaScript" ".NET" "Java" "Go" >}}
<!-- Python -->
{{% codetab %}}
### Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [Python 3.7+ installed](https://www.python.org/downloads/).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 1: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/state_management/python/sdk).
```bash
git clone https://github.com/dapr/quickstarts.git
```
### Step 2: Manipulate service state
In a terminal window, navigate to the `order-processor` directory.
```bash
cd state_management/python/sdk/order-processor
```
Install the dependencies:
```bash
pip3 install -r requirements.txt
```
Run the `order-processor` service alongside a Dapr sidecar.
```bash
dapr run --app-id order-processor --resources-path ../../../resources/ -- python3 app.py
```
> **Note**: Since Python3.exe is not defined in Windows, you may need to use `python app.py` instead of `python3 app.py`.
The `order-processor` service writes, reads, and deletes an `orderId` key/value pair to the `statestore` instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). As soon as the service starts, it performs a loop.
```python
with DaprClient() as client:
# Save state into the state store
client.save_state(DAPR_STORE_NAME, orderId, str(order))
logging.info('Saving Order: %s', order)
# Get state from the state store
result = client.get_state(DAPR_STORE_NAME, orderId)
logging.info('Result after get: ' + str(result.data))
# Delete state from the state store
client.delete_state(store_name=DAPR_STORE_NAME, key=orderId)
logging.info('Deleting Order: %s', order)
```
### Step 3: View the order-processor outputs
Notice, as specified in the code above, the code saves application state in the Dapr state store, reads it, then deletes it.
Order-processor output:
```
== APP == INFO:root:Saving Order: {'orderId': '1'}
== APP == INFO:root:Result after get: b"{'orderId': '1'}"
== APP == INFO:root:Deleting Order: {'orderId': '1'}
== APP == INFO:root:Saving Order: {'orderId': '2'}
== APP == INFO:root:Result after get: b"{'orderId': '2'}"
== APP == INFO:root:Deleting Order: {'orderId': '2'}
== APP == INFO:root:Saving Order: {'orderId': '3'}
== APP == INFO:root:Result after get: b"{'orderId': '3'}"
== APP == INFO:root:Deleting Order: {'orderId': '3'}
== APP == INFO:root:Saving Order: {'orderId': '4'}
== APP == INFO:root:Result after get: b"{'orderId': '4'}"
== APP == INFO:root:Deleting Order: {'orderId': '4'}
```
##### `statestore.yaml` component file
When you run `dapr init`, Dapr creates a default Redis `statestore.yaml` and runs a Redis container on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out the [state store](/reference/components-reference/supported-state-stores/) without making code changes.
The Redis `statestore.yaml` file included for this quickstart contains the following:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
```
In the YAML file:
- `metadata/name` is how your application talks to the component (called `DAPR_STORE_NAME` in the code sample).
- `spec/metadata` defines the connection to the Redis instance used by the component.
{{% /codetab %}}
<!-- JavaScript -->
{{% codetab %}}
### Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [Latest Node.js installed](https://nodejs.org/download/).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 1: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/state_management/javascript/sdk).
```bash
git clone https://github.com/dapr/quickstarts.git
```
### Step 2: Manipulate service state
In a terminal window, navigate to the `order-processor` directory.
```bash
cd state_management/javascript/sdk/order-processor
```
Install dependencies, which will include the `@dapr/dapr` package from the JavaScript SDK:
```bash
npm install
```
Verify you have the following files included in the service directory:
- `package.json`
- `package-lock.json`
Run the `order-processor` service alongside a Dapr sidecar.
```bash
dapr run --app-id order-processor --resources-path ../../../resources/ -- npm run start
```
The `order-processor` service writes, reads, and deletes an `orderId` key/value pair to the `statestore` instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). As soon as the service starts, it performs a loop.
```js
const client = new DaprClient()
// Save state into a state store
await client.state.save(DAPR_STATE_STORE_NAME, order)
console.log("Saving Order: ", order)
// Get state from a state store
const savedOrder = await client.state.get(DAPR_STATE_STORE_NAME, order.orderId)
console.log("Getting Order: ", savedOrder)
// Delete state from the state store
await client.state.delete(DAPR_STATE_STORE_NAME, order.orderId)
console.log("Deleting Order: ", order)
```
### Step 3: View the order-processor outputs
Notice, as specified in the code above, the code saves application state in the Dapr state store, reads it, then deletes it.
Order-processor output:
```
== APP == > order-processor@1.0.0 start
== APP == > node index.js
== APP == Saving Order: { orderId: 1 }
== APP == Saving Order: { orderId: 2 }
== APP == Saving Order: { orderId: 3 }
== APP == Saving Order: { orderId: 4 }
== APP == Saving Order: { orderId: 5 }
== APP == Getting Order: { orderId: 1 }
== APP == Deleting Order: { orderId: 1 }
== APP == Getting Order: { orderId: 2 }
== APP == Deleting Order: { orderId: 2 }
== APP == Getting Order: { orderId: 3 }
== APP == Deleting Order: { orderId: 3 }
== APP == Getting Order: { orderId: 4 }
== APP == Deleting Order: { orderId: 4 }
== APP == Getting Order: { orderId: 5 }
== APP == Deleting Order: { orderId: 5 }
```
##### `statestore.yaml` component file
When you run `dapr init`, Dapr creates a default Redis `statestore.yaml` and runs a Redis container on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out the [state store](/reference/components-reference/supported-state-stores/) without making code changes.
The Redis `statestore.yaml` file included for this quickstart contains the following:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
```
In the YAML file:
- `metadata/name` is how your application talks to the component (called `DAPR_STORE_NAME` in the code sample).
- `spec/metadata` defines the connection to the Redis instance used by the component.
{{% /codetab %}}
<!-- .NET -->
{{% codetab %}}
### Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [.NET SDK or .NET 6 SDK installed](https://dotnet.microsoft.com/download).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 1: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/state_management/csharp/sdk).
```bash
git clone https://github.com/dapr/quickstarts.git
```
### Step 2: Manipulate service state
In a terminal window, navigate to the `order-processor` directory.
```bash
cd state_management/csharp/sdk/order-processor
```
Recall NuGet packages:
```bash
dotnet restore
dotnet build
```
Run the `order-processor` service alongside a Dapr sidecar.
```bash
dapr run --app-id order-processor --resources-path ../../../resources/ -- dotnet run
```
The `order-processor` service writes, reads, and deletes an `orderId` key/value pair to the `statestore` instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). As soon as the service starts, it performs a loop.
```cs
var client = new DaprClientBuilder().Build();
// Save state into the state store
await client.SaveStateAsync(DAPR_STORE_NAME, orderId.ToString(), order.ToString());
Console.WriteLine("Saving Order: " + order);
// Get state from the state store
var result = await client.GetStateAsync<string>(DAPR_STORE_NAME, orderId.ToString());
Console.WriteLine("Getting Order: " + result);
// Delete state from the state store
await client.DeleteStateAsync(DAPR_STORE_NAME, orderId.ToString());
Console.WriteLine("Deleting Order: " + order);
```
### Step 3: View the order-processor outputs
Notice, as specified in the code above, the code saves application state in the Dapr state store, reads it, then deletes it.
Order-processor output:
```
== APP == Saving Order: Order { orderId = 1 }
== APP == Getting Order: Order { orderId = 1 }
== APP == Deleting Order: Order { orderId = 1 }
== APP == Saving Order: Order { orderId = 2 }
== APP == Getting Order: Order { orderId = 2 }
== APP == Deleting Order: Order { orderId = 2 }
== APP == Saving Order: Order { orderId = 3 }
== APP == Getting Order: Order { orderId = 3 }
== APP == Deleting Order: Order { orderId = 3 }
== APP == Saving Order: Order { orderId = 4 }
== APP == Getting Order: Order { orderId = 4 }
== APP == Deleting Order: Order { orderId = 4 }
== APP == Saving Order: Order { orderId = 5 }
== APP == Getting Order: Order { orderId = 5 }
== APP == Deleting Order: Order { orderId = 5 }
```
##### `statestore.yaml` component file
When you run `dapr init`, Dapr creates a default Redis `statestore.yaml` and runs a Redis container on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out the [state store](/reference/components-reference/supported-state-stores/) without making code changes.
The Redis `statestore.yaml` file included for this quickstart contains the following:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
```
In the YAML file:
- `metadata/name` is how your application talks to the component (called `DAPR_STORE_NAME` in the code sample).
- `spec/metadata` defines the connection to the Redis instance used by the component.
{{% /codetab %}}
<!-- Java -->
{{% codetab %}}
### Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- Java JDK 17 (or greater):
- [Oracle JDK](https://www.oracle.com/java/technologies/downloads), or
- OpenJDK
- [Apache Maven](https://maven.apache.org/install.html), version 3.x.
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 1: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/state_management/java/sdk).
```bash
git clone https://github.com/dapr/quickstarts.git
```
### Step 2: Manipulate service state
In a terminal window, navigate to the `order-processor` directory.
```bash
cd state_management/java/sdk/order-processor
```
Install the dependencies:
```bash
mvn clean install
```
Run the `order-processor` service alongside a Dapr sidecar.
```bash
dapr run --app-id order-processor --resources-path ../../../resources -- java -jar target/OrderProcessingService-0.0.1-SNAPSHOT.jar
```
The `order-processor` service writes, reads, and deletes an `orderId` key/value pair to the `statestore` instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). As soon as the service starts, it performs a loop.
```java
try (DaprClient client = new DaprClientBuilder().build()) {
for (int i = 1; i <= 10; i++) {
int orderId = i;
Order order = new Order();
order.setOrderId(orderId);
// Save state into the state store
client.saveState(DAPR_STATE_STORE, String.valueOf(orderId), order).block();
LOGGER.info("Saving Order: " + order.getOrderId());
// Get state from the state store
State<Order> response = client.getState(DAPR_STATE_STORE, String.valueOf(orderId), Order.class).block();
LOGGER.info("Getting Order: " + response.getValue().getOrderId());
// Delete state from the state store
client.deleteState(DAPR_STATE_STORE, String.valueOf(orderId)).block();
LOGGER.info("Deleting Order: " + orderId);
TimeUnit.MILLISECONDS.sleep(1000);
}
```
### Step 3: View the order-processor outputs
Notice, as specified in the code above, the code saves application state in the Dapr state store, reads it, then deletes it.
Order-processor output:
```
== APP == INFO:root:Saving Order: {'orderId': '1'}
== APP == INFO:root:Result after get: b"{'orderId': '1'}"
== APP == INFO:root:Deleting Order: {'orderId': '1'}
== APP == INFO:root:Saving Order: {'orderId': '2'}
== APP == INFO:root:Result after get: b"{'orderId': '2'}"
== APP == INFO:root:Deleting Order: {'orderId': '2'}
== APP == INFO:root:Saving Order: {'orderId': '3'}
== APP == INFO:root:Result after get: b"{'orderId': '3'}"
== APP == INFO:root:Deleting Order: {'orderId': '3'}
== APP == INFO:root:Saving Order: {'orderId': '4'}
== APP == INFO:root:Result after get: b"{'orderId': '4'}"
== APP == INFO:root:Deleting Order: {'orderId': '4'}
```
##### `statestore.yaml` component file
When you run `dapr init`, Dapr creates a default Redis `statestore.yaml` and runs a Redis container on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out the [state store](/reference/components-reference/supported-state-stores/) without making code changes.
The Redis `statestore.yaml` file included for this Quickstart contains the following:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
```
In the YAML file:
- `metadata/name` is how your application talks to the component (called `DAPR_STORE_NAME` in the code sample).
- `spec/metadata` defines the connection to the Redis instance used by the component.
{{% /codetab %}}
<!-- Go -->
{{% codetab %}}
### Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [Latest version of Go](https://go.dev/dl/).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 1: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/state_management/go/sdk).
```bash
git clone https://github.com/dapr/quickstarts.git
```
### Step 2: Manipulate service state
In a terminal window, navigate to the `order-processor` directory.
```bash
cd state_management/go/sdk/order-processor
```
Install the dependencies and build the application:
```bash
go build .
```
Run the `order-processor` service alongside a Dapr sidecar.
```bash
dapr run --app-id order-processor --resources-path ../../../resources -- go run .
```
The `order-processor` service writes, reads, and deletes an `orderId` key/value pair to the `statestore` instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). As soon as the service starts, it performs a loop.
```go
client, err := dapr.NewClient()
// Save state into the state store
_ = client.SaveState(ctx, STATE_STORE_NAME, strconv.Itoa(orderId), []byte(order))
log.Print("Saving Order: " + string(order))
// Get state from the state store
result, _ := client.GetState(ctx, STATE_STORE_NAME, strconv.Itoa(orderId))
fmt.Println("Getting Order: " + string(result.Value))
// Delete state from the state store
_ = client.DeleteState(ctx, STATE_STORE_NAME, strconv.Itoa(orderId))
log.Print("Deleting Order: " + string(order))
```
### Step 3: View the order-processor outputs
Notice, as specified in the code above, the code saves application state in the Dapr state store, reads it, then deletes it.
Order-processor output:
```
== APP == dapr client initializing for: 127.0.0.1:53689
== APP == 2022/04/01 09:16:03 Saving Order: {"orderId":1}
== APP == Getting Order: {"orderId":1}
== APP == 2022/04/01 09:16:03 Deleting Order: {"orderId":1}
== APP == 2022/04/01 09:16:03 Saving Order: {"orderId":2}
== APP == Getting Order: {"orderId":2}
== APP == 2022/04/01 09:16:03 Deleting Order: {"orderId":2}
== APP == 2022/04/01 09:16:03 Saving Order: {"orderId":3}
== APP == Getting Order: {"orderId":3}
== APP == 2022/04/01 09:16:03 Deleting Order: {"orderId":3}
== APP == 2022/04/01 09:16:03 Saving Order: {"orderId":4}
== APP == Getting Order: {"orderId":4}
== APP == 2022/04/01 09:16:03 Deleting Order: {"orderId":4}
== APP == 2022/04/01 09:16:03 Saving Order: {"orderId":5}
== APP == Getting Order: {"orderId":5}
== APP == 2022/04/01 09:16:03 Deleting Order: {"orderId":5}
```
##### `statestore.yaml` component file
When you run `dapr init`, Dapr creates a default Redis `statestore.yaml` and runs a Redis container on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out the [state store](/reference/components-reference/supported-state-stores/) without making code changes.
The Redis `statestore.yaml` file included for this Quickstart contains the following:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
```
In the YAML file:
- `metadata/name` is how your application talks to the component (called `DAPR_STORE_NAME` in the code sample).
- `spec/metadata` defines the connection to the Redis instance used by the component.
{{% /codetab %}}
{{< /tabs >}}
## Tell us what you think!
We're continuously working to improve our Quickstart examples and value your feedback. Did you find this quickstart helpful? Do you have suggestions for improvement?
Join the discussion in our [discord channel](https://discord.com/channels/778680217417809931/953427615916638238).
## Next steps
- Use Dapr State Management with HTTP instead of an SDK.
- [Python](https://github.com/dapr/quickstarts/tree/master/state_management/python/http)
- [JavaScript](https://github.com/dapr/quickstarts/tree/master/state_management/javascript/http)
- [.NET](https://github.com/dapr/quickstarts/tree/master/state_management/csharp/http)
- [Java](https://github.com/dapr/quickstarts/tree/master/state_management/java/http)
- [Go](https://github.com/dapr/quickstarts/tree/master/state_management/go/http)
- Learn more about [State Management building block]({{< ref state-management >}})
{{< button text="Explore Dapr tutorials >>" page="getting-started/tutorials/_index.md" >}}