ローカルマシンでいち早くDaprを動作させる手順

# はじめに

本記事は、企画「QiitaAzure記事投稿キャンペーン」の2021年6月のテーマ「[Microsoft Buildで発表された技術情報に関する記事を投稿しよう！](https://qiita.com/official-events/885e4031d03c787eceab)」への参加記事です。

参加条件には、2021年5月26日〜28日に開催された「Microsoft Build 2021」で発表されたテクノロジーに関する内容であることが求められています。

現在、個人的に「Dapr」にハマりかけており、関連するセッション動画があれば参加できるのになぁと思いながら検索したところ...まさに奇跡!? 何と１件だけヒットしました！

- [MyBuild - Microservices made easy with Dapr](https://mybuild.microsoft.com/sessions/a5648d1d-b523-4549-a2bc-a0ad226cfe2a?source=sessions
)

これにより、参加条件を満たすることができたと思い、今回投稿してみました。

# Daprとは？

Daprは、分散アプリケーションランタイムです。

- [Dapr - Distributed Application Runtime](https://dapr.io/)

分散アプリケーションにおける、各サービスの紐付け、状態やシークレットの管理、Pub/Sub、観測などをブロックやコンポーネントとして扱うことで、自由に組み合わせて機能を構築できます。

また、インフラ側は様々なクラウドやエッジに、アプリケーション側は様々なプログラミング言語に対応しているため、こちらも自由に組み合わせて開発できます。

Gopherとしては、Go製オープンソースソフトウェアである点が、マルチクラウドファンとしては、各社のパブリッククラウドサービスをマッシュアップできる点が、大きな魅力となっています。

詳細につきましては、次のドキュメントを参照してみてください。（現在、私も読み進めている最中！）

- [Dapr Docs](https://docs.dapr.io/)（英語）
- [.NET 開発者向け Dapr | Microsoft Docs](
https://docs.microsoft.com/ja-jp/dotnet/architecture/dapr-for-net-developers/)（日本語）

# 準備手順

基本的には、Dapr公式ドキュメント「[Getting started with Dapr](https://docs.dapr.io/getting-started/)」の1.〜3.に従って進めて行きます。

1. Install the Dapr CLI
1. Initialize Dapr
1. Use the Dapr API

## 前提条件

今回の対象OSはmacOSです。

## Dapr CLIのインストール

Dapr公式ドキュメント「[Install the Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)」にて、「MacOS」タブ内では、`curl`や`brew`のコマンドでインストールする手順が紹介されています。

私は自分の責任で配置したいため、ここでは「Binaries」タブ内で紹介されている「[Dapr Release](https://github.com/dapr/cli/releases)」にアクセスして、macOS版である「dapr_darwin_amd64.tar.gz」を選択＆ダウンロードして、`tar`コマンドで展開しました。

```shell
tar zxvf dapr_darwin_amd64.tar.gz
```

`dapr`コマンドが展開されるので、実行して動作確認します。

```shell
./dapr -v
CLI version: 1.2.0 
Runtime version: 1.2.2
```

## ローカル環境でのDaprの初期化

Dapr公式ドキュメント「[Initialize Dapr in your local environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/)」には、Dockerの使用を前提とした初期化の手順が紹介されています。

私はDockerなしで動作させたいため、ここではDapr公式ドキュメント「[How-To: Run Dapr in self-hosted mode without Docker](https://docs.dapr.io/operations/hosting/self-hosted/self-hosted-no-docker/)」に従って、Dockerなしの方法で初期化します。

Daprを最小単位で初期化します。

```shell
dapr init --slim
```

この時、ホームディレクトリー配下に`.dapr/`ディレクトリーが作成されます。

```shell
$HOME/.dapr/
|
+--bin/
|  |
|  +--daprd
|  +--dashboard
|  +--placement
|  +--web/
|
+--components/
+--config.yaml
```

## Redis

Redisは、オープンソースのメモリ内データ構造ストアです。

- [Redis](https://redis.io/)

Dapr公式ドキュメントでは、状態を保存するために「Redis」を使う内容になっているため、Redisをダウンロード＆セットアップします。

Redis公式ドキュメント「[Redis Quick Start](https://redis.io/topics/quickstart)」を読み進めると、Redisのダウンロードには`wget`コマンドを使うようになっていますが、私のmacOSには`wget`コマンドは入っていないので、Webブラウザーにてダウンロードします。

Redis公式ドキュメントで紹介されていた「download.redis.io/redis-stable.tar.gz」リンクをクリックしてもダウンロードできなかったため、Redis公式サイトの「[Download](https://redis.io/download)」に遷移して、Stable版の「Download X.Y.Z」をクリックしてダウンロードしました。

ダウンロード後、Redis公式ドキュメントの手順に従って展開＆コンパイルします。

```shell
tar xvzf redis-X.Y.Z.tar.gz
cd redis-X.Y.Z
make
```

Redisサーバーを起動します。

```shell
./src/redis-server
```

別ターミナルを立ち上げて、Redis CLIを実行して動作を確認します。

```shell
./src/redis-cli ping
PONG
```

Dapr公式ドキュメント「[Initialize Dapr in your local environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/)」に戻ると、観測には「Zipkin」を、アクターには「Dapr placement」を使うように記載されています。

Zipkinは、オープンソースの分散トレースシステムです。

- [OpenZipkin · A distributed tracing system](https://zipkin.io/)

Java 8以上で動作するのですが、私のmacOSにはJava 8が入っていないため、Javaのインストール手順から書き始めなければならず、そうすると最小限ではなくなってしまうため、今回は対象外とします。後日、記事を書いた際にはリンクを貼っておきます。

Dapr placementは、Dapr公式ドキュメントの通り、次のコマンドで起動できます。

```shell
$HOME/.dapr/bin/placement
```

## DaprとRedisの紐付け

Daprでは、状態を管理する機能はビルディングブロック「ステートストア」です。

Daprと各サービスの紐付けは、yamlファイルに設定値を記述することで行います。

今回の場合、`$HOME/.dapr/components/`ディレクトリー配下に「statestore.yaml」ファイルを作成します。ファイル名は任意で大丈夫です。

作成したYAMLファイルの内容は、以下のリンク先で紹介されていますので、コピー＆ペーストしてください。

- Dapr の状態管理構成ブロック | Microsoft Docs - [構成](https://docs.microsoft.com/ja-jp/dotnet/architecture/dapr-for-net-developers/state-management#configuration)

```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"
```

RedisのYAMLファイルの詳細については、以下を参照してください。

- [Redis | Dapr Docs](https://docs.dapr.io/reference/components-reference/supported-state-stores/setup-redis/
)

## Dapr APIを使う

Dapr公式ドキュメント「[Use the Dapr API](https://docs.dapr.io/getting-started/get-started-api/)」の内容に従って、ステートの保存と読み出しを試みます。

Daprでは、アプリケーションと通信するためのHTTP/gRPCインターフェースとそれに紐付くビルディングブロックを合わせたものを「サイドカー」と呼びます。

`dapr run`コマンドで、アプリケーションとサイドカーを起動します。

Dapr公式ドキュメントの例では、アプリケーションがない状態で、アプリケーションIDを「myapp」として、サイドカーのポート番号を「3500」にして、Daprを起動しています。

```shell
./dapr run --app-id myapp --dapr-http-port 3500
```

Daprのステートストアで管理できるデータはキーバリューです。

Dapr公式ドキュメントの例では、データをJSONで表しています。

```JSON
[
  {
    "key": "name",
    "value": "Bruce Wayne"
  }
]
```

`curl`コマンドにて、URLにステータスストアのエンドポイント`v1.0/state`とメタデータ名`statestore`を指定して、HTTP通信のPOSTメソッドでJSONデータを送信して保存します。

```shell
curl -X POST -H "Content-Type: application/json" -d '[{ "key": "name", "value": "Bruce Wayne"}]' http://localhost:3500/v1.0/state/statestore
```

`curl`コマンドにて、URLにステータスストアのエンドポイント`v1.0/state`とメタデータ名`statestore`と保存したデータのキー項目値`name`を指定して、HTTP通信にてメタデータ名`statestore`に保存したデータのキー項目値`name`のバリュー値を取得します。

```shell
curl http://localhost:3500/v1.0/state/statestore/name
"Bruce Wayne"
```

Redis CLIを対話モードで起動して、保存されたデータを確認します。

```shell
./src/redis-cli
127.0.0.1:6379> keys *
1) "myapp||name"
127.0.0.1:6379> hgetall "myapp||name"
1) "data"
2) "\"Bruce Wayne\""
3) "version"
4) "1"
127.0.0.1:6379> exit
```

## 各サーバーの停止

`dapr`コマンドにて、アプリケーションIDを指定してDaprを停止します。

```shell
./dapr stop --app-id myapp
```

Redis CLIでRedisサーバーを停止します。

```shell
./src/redis-cli shutdown
```

# さいごに

企画の締め切りもあり、まずはローカルマシンでいち早くDaprの鼓動を実感するところまでを紹介させて頂きました。

Dockerが使える方は、Dapr公式ドキュメントに従って是非`dapr init`コマンドでの使い方を進めてみてください。

DaprとDapr CLIのインストールはGoのソースコードからビルドしたいところ！