Dapr Advent Calendar 2日目 - DaprでHello World
こんにちは、Dapr Advent Calendar 2日目です。3日坊主まであと1日です。
Hello Worldを動かしてみよう
前回はDapr CLIをインストールして動かしてみただけですが、今回はDaprとともにWebアプリケーションを起動して呼び出すところまで説明します。
動かすアプリケーションは、もちろん、プログラミング界で最も著名なアプリケーション「Hello World」です。
Webアプリケーションの作成
まずはWebアプリケーションの作成です。Hello Worldをサクッと作りましょう。
Spring BootでこのようなControllerクラスを作りました。
HelloController.java(抜粋)
@RestController public class HelloController { @GetMapping("/hello") public Map<String, String> hello() { return Map.of("message", "Hello, world!"); } }
https://github.com/cero-t/dapr-advent-2021
このソースコードの例ではMavenのマルチモジュール構成で、次のように作ってあります。
まずはWebアプリケーション「hello」を単体で起動します。
../mvnw spring-boot:run
アプリケーションが起動したらcurlコマンドでアクセスします。
curl localhost:8080/hello
無事に実行結果が表示されました。
{"message":"Hello, world!"}
Daprとともにアプリケーションを起動
続いて、Daprを使ってアプリケーションを起動します。
上で起動したアプリケーションを一旦停止させた後、次のコマンドで起動します。
dapr run --app-id hello-app --app-port 8080 --dapr-http-port 18080 ../mvnw spring-boot:run
コマンドの引数についての詳しい説明はあとで行います。
起動に成功すると、WebアプリケーションのログとDaprのログが両方ともコンソールに表示されるはずです。
(前半部分は割愛) == APP == 2021-12-02 00:00:00.000 INFO 58739 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' == APP == 2021-12-02 00:00:00.000 INFO 58739 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' == APP == 2021-12-02 00:00:00.000 INFO 58739 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms INFO[0003] application configuration loaded app_id=hello-app instance=macmini.local scope=dapr.runtime type=log ver=1.5.0 INFO[0003] actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s app_id=hello-app instance=macmini.local scope=dapr.runtime.actor type=log ver=1.5.0 INFO[0003] dapr initialized. Status: Running. Init Elapsed 3540.333ms app_id=hello-app instance=macmini.local scope=dapr.runtime type=log ver=1.5.0 INFO[0005] placement tables updated, version: 0 app_id=hello-app instance=macmini.local scope=dapr.runtime.actor.internal.placement type=log ver=1.5.0
ここまで表示されれば起動は完了です。
もしここで次のエラーが出た場合はDaprの初期化が済んでいない可能性が高いので dapr init
コマンドを実行してください。
ℹ️ Starting Dapr with id hello-app. HTTP Port: 18080. gRPC Port: 60117 ❌ fork/exec /Users/(ユーザ名)/.dapr/bin/daprd: no such file or directory
それでは起動したDapr経由で、Webアプリケーションにアクセスしてみましょう。curlコマンドでアクセスします。
curl localhost:18080/v1.0/invoke/hello-app/method/hello
URLが少しややこしいのですが、このURLの詳細についてもあとで説明します。
ふつうにアクセスした時と同じ実行結果が表示されました。
{"message":"Hello, world!"}
dapr list
コマンドで、起動中のDaprアプリケーションを確認することができます。
dapr list
先ほど起動した hello-app
が表示されます。
APP ID HTTP PORT GRPC PORT APP PORT COMMAND AGE CREATED PID hello-app 18080 61164 8080 ../mvnw spring-bo... 1m 2021-12-02 00:00.00 59584
なお dapr run
コマンドで起動したアプリケーションは、特にコンテナの中で動いているなどではなく、普通のプロセスとして起動しているだけなので、Daprを経由せずにアクセスすることもできます。
curl localhost:8080/hello
{"message":"Hello, world!"}
Dapr経由でアクセスしようとしたけどなぜかアクセスできない、という時にはアプリケーションに直接アクセスして正常に動作しているかを確認してみてください。
やったことの解説
それでは打ったコマンドなどについて説明します。
起動オプション
今回はDaprを次のコマンドで起動しました。
dapr run --app-id hello-app --app-port 8080 --dapr-http-port 18080 ../mvnw spring-boot:run
dapr run
コマンドが、Daprの起動コマンドです。このコマンドでアプリケーションを起動します。ちなみに何の引数も指定せずに dapr run
だけ実行してもDaprのプロセスを立ち上げることができます。
--app-id
がアプリケーションのIDです。任意の名前を指定することができます。Daprはアプリケーションをこのapp-idで識別していて、アプリケーションをinvokeする時などに利用します。省略すると自動的にIDが発行されます。
--app-port
がWebアプリケーションのポート番号です。Hello Worldアプリケーションは8080番ポートで起動しているため、そのポート番号を指定します。省略すると0番ポートが指定されてしまってアプリケーションにアクセスできなくなるため、必ず指定してください。
--dapr-http-port
がDapr側のポート番号です。任意のポート番号を指定できます。Daprにアクセスする際にはこのポートを利用します。省略するとランダムなポート番号が指定されます。
../mvnw spring-boot:run
の部分がアプリケーションの起動コマンドです。
アプリケーションの起動コマンドに引数を渡す場合は、起動コマンドの前に --
を追加する必要があります。たとえばアプリケーションの起動を java -jar
コマンドで行う場合は次のようなコマンドになります。
../mvnw clean package dapr run --app-id hello-app --app-port 8080 --dapr-http-port 18080 -- java -jar target/hello-1.0.0.jar
javaコマンドの前に --
をつけているところがポイントです。
その他のコマンド一覧
もちろんコマンド引数は他にもあり、このページに一覧が掲載されています。
https://docs.dapr.io/reference/arguments-annotations-overview/
また dapr run --help
コマンドを実行すると、dapr run
コマンドに対する引数の一覧を見ることができます。
Daprからアプリケーションへのアクセス
Dapr経由でWebアプリケーションにアクセスする際に、次のコマンドを用いました。
curl localhost:18080/v1.0/invoke/hello-app/method/hello
18080
がDaprのポート番号です。
/v1.0
がDaprのAPIバージョンで、今のところ v1.0
しかありません。
/invoke
がInvoke APIで、起動したWebアプリケーションにアクセスするAPIになります。他にもデータを保存する /state
や、エンキューを行う /pubsub
などのAPIがあります。
Invoke APIは /invoke/(app-id)/method/(アプリケーションのパス)
という形式になります。今回は app-id
に hello-app
を指定し、アプリケーションのパスは /hello
を指定しました。これで localhost:8080/hello
にアクセスするのと同じになります。
その他のアクセス方法
DaprのInvoke APIは、Dapr CLIを用いて実行することもできます。
dapr invoke --app-id hello-app --method hello --verb GET
このCLIはverbを指定しないと POST
となるため、GETリクエストしたい場合は --verb GET
を指定します。
また、Daprのv1.4からInvoke APIを別のURLでも起動できるようになりました。
curl -H 'dapr-app-id:hello-app' localhost:18080/hello curl dapr-app-id:hello-app@localhost:18080/hello
Daprを運用する際に「パスの書き換えはできないけど任意のヘッダを付けることができる」ようなミドルウェアを利用している場合には、この形式のURLを用いてアクセスすることができるようになりそうですが、実際に使ったことがないのでどれくらい便利になるかはちょっと説明できません。てへぺろ。
まとめ
それでは今回の内容を簡単に振り返りましょう。
dapr run
コマンドでDaprとともにWebアプリケーションを起動することができます- Invoke APIを用いてDapr経由でWebアプリケーションにアクセスができます
- WebアプリケーションそのものもローカルPC上で起動しているため、直接アクセスすることができます
今のところDaprの良さは何も引き出していませんが、次回からはDaprの便利な機能を利用していきます!