Play 2.0 Javaのオススメと
   1.2からのアップグレード



          原 一浩 @kara_d
原 一浩   @kara_d   http://greative.jp/
何してる人?




         Greative is Great Creative
    デザイントレンド、統計(R)、システム
本日のアジェンダ
➡   まえがき:何故 2.0 Javaなのか?
➡   基本編:1.2.x -> 2.0.x Javaへ
➡   コラム:2.0.xの導入のしどころ
➡   応用編:1.2.xを2.0.xライクに使おう




                               4
まえがき:何故 2.0 Javaなのか?
ご存知ない方もいるかもしれませんが、
Play 2.0ではJavaで開発できる機能が
あります




                          6
ビジネス要件にマッチ
➡   受託制作をメインでやってます
➡   プレゼンの際にJavaベースで通せる


    •   プログラム言語のプレゼンテーション          ここ結構大変

    •   フレームワークのプレゼンテーション

    •   プロジェクト自体のプレゼンテーション


➡   Javaのブランドの積み重ねはすごい
➡   Railsぽくスピーディに開発したい
    •   比較対象に、PHP、Rubyのフレームワークが入ってきたりする


                                            7
コラボレーション上の選択
➡   開発者人数の圧倒的な差(世界で900万人とも)
➡   引き継ぎのしやすさ
    •   クライアント社内でJavaのメンテが出来たりなど

➡   そもそもフリーで、Scalaできて、忙しくない人を
    あまりしらない(仲良くしてください^^)

Javaの進化により、回帰するんじゃないか説
➡   Java 7、Java 8は、モダンな仕組みも取り入れつつ
    よくなっていくぽい気がする
➡   Xtendとかもよかったりして


                                    8
Xtend
➡   個人的な興味
    •   http://www.eclipse.org/xtend/




                                        9
新しいことへは挑戦したいので
➡   基本のアプリケーションは、2.0 Javaで開発
➡   Scalaは、汎用のプラグインを作る際に使用し、
    それをプロジェクトに導入
    •   「弊社プラグインをライブラリとして採用してます」的な

➡   コンソール用のツールはsbtプラグインで作成
➡   Scalaは、まだまだ勉強中

          このへんはそれぞれの立場によりますね...




                                     10
基本編:1.2.x -> 2.0.x Javaへ
本体のフォルダ構成の変更をまず見てみる




                      12
Play 1.2.5本体のフォルダ構成
➡   /documentation
➡   /framework
➡   /modules
➡   /python
➡   README.textile
➡   /resources
➡   /samples-and-tests
➡   /support




                         13
1.2.xのEclipseプラグイン:Routes
➡   最近、良さに気づきました(遅




                            14
1.2.xのEclipseプラグイン:View
➡   Viewもバッチリ。2.0もSublimeTextにはプラグインあり




                                         15
1.2.xのEclipseプラグイン:Tools




                  New Controller
                  New View
                  New Model
                  Go Routes

ショートカットがMVC!!

          2.0版もはやく欲しい!!

                                   16
Play 2.0.x本体のフォルダ構成
➡   /documentation
    •   Play 2.0 Documentation.pdf   必須

➡   /framework
    •   src/play/src/main/java

    •   src/play/src/main/scala

➡   README.md
➡   /repository
➡   /samples
➡   /support


                                          17
モデルの大幅な変更




            18
モデルの大幅な変更
➡   1.2.x
    •   JPA拡張

    •   play.db.jpa.GenericModelクラスを継承したモデルを作る事で
        下記を利用可能
        - create()、find()、findAll()、save()、edit()、delete()....

➡   2.0.x
    •   Ebean     ebeanEnabled := true/false

    •   play.db.ebean.EbeanPluginクラスがある

    •   play.db.ebean.Modelクラスを継承

    •   1.2よりも薄いラッパー


                モデルは、書き直すか、JPAを利用
                                                               19
Ebeanって ( Д )?
➡   Ebean is an open source (LGPL license) Java Object Relational
    Mapping tool. It uses JPA Annotations (@entity, @OneToMany ...) for
    mapping.



➡   メソッドチェーンでSQLぽく組み立てる

    Order	
  order	
  =	
  Ebean.find(Order.class)	
  	
  
    	
  	
  	
  	
  	
  	
  	
  	
  .select("orderDate")	
  	
  
    	
  	
  	
  	
  	
  	
  	
  	
  .where().idEq(12)	
  	
  
    	
  	
  	
  	
  	
  	
  	
  	
  .findUnique();	
  	
  


➡   既に豊富なドキュメントがある
    •   http://www.avaje.org/doc/ebean-userguide.pdf

                                                                          20
コントローラの変更




            21
コントローラーの考え方が変更
➡   1.2.x
    •   render()、renderText()、renderHtml()、renderJson()...

    •   アクションの返り値は、なし(void)

➡   2.0.x
    •   ok()、notFound()、internalServerError()、forbidden()

    •   アクションの返り値は、Result型



              HTTPプロトコルのレスポンスを再現

                 設定より規約 → 規約より型

                      大幅に書き換えが必要
                                                             22
JSONの扱い
➡   1.2.x
    •   Gson
        - RenderJSON()などで使用

➡   2.0.x
    •   Jackson(Scalaでは、Jerkson)
        - WebSocketなどで使用


                JSONを使っている場合は修正




                                   23
認証周り
➡   1.2.x
    •   SECUREモジュールを使用(標準)

➡   2.0.x
    •   AuthenticityToken module for Play2!(後述)

    •   play-authenticate
        - http://joscha.github.com/play-authenticate/

    •   Deadbolt2
        - http://www.playframework.org/modules/deadbolt


               複数のモジュールの組み合わせで対応


                                                          24
Play 2.0.xのビューについて




                     25
一番変化が激しいビュー
➡   1.2.x
    •   GroovyTemplate

    •   よくある${hoge}、#{hoge}、@{hoge}というスタイル

    •   複雑なタグはFastTagを使う

➡   2.0.x
    •   ScalaTemplate

    •   Microsoft Razorライクなシンタックス

    •   最終的にはScalaの関数になる

    •   複雑なタグは単純にJavaのクラスで実装可能


                    全体的な修正、もしくは...

                                             26
Play 2.0でGroovy Template
➡   Groovy Template Engine for Play 2
    •   https://github.com/mbknor/gt-engine-play2/


    •   ほとんどのGroovyTemplateが使用可能

    •   FastTagも使用可能とのこと(試したところウマく動かず)


                    ほぼ修正なしでいけるぽい




                                                     27
Razorって? ( Д )
➡   @を利用してテンプレート式のブロックを示す
➡   @を使う場合は@@と記述
➡   @以降は、Scala(本家はC#)コードに変換
➡   @{}で複数行
➡   文中の{}も全てパースされる
    •   つまり「{」が片方しか無いとエラー

    •   play2-short-filter
        - https://github.com/karad/play2-short-filtr
        - @r("{")というかんじで使える




                                                      28
CSRF対策
➡   1.2.x
    •   自動

➡   2.0.x
    •   AuthenticityToken module for Play2!
        - https://github.com/orefalo/play2-authenticitytoken


    import	
  authtoken.validator.AuthenticityToken;
    @Entity	
  
    public	
  class	
  Page	
  extends	
  Model{
    	
  	
  	
  	
  @Transient
    	
  	
  	
  	
  @AuthenticityToken
    	
  	
  	
  	
  public	
  String	
  authtoken;
    }

                                                               29
プラグイン(モジュール)の違い




                  30
モジュールのルートに関する考え方の違い
➡   1.2.x
    •   モジュールはroutesに定義
        - GET   /    module:site

    •   routesの入れ子が可能
        - GET   /?   site.Site.index

➡   2.0.x
    •   パッケージの宣言による

    •   フラットにroutesを管理できる印象


                      sbtプラグイン化が良い


                                       31
コンソールが作りやすくなった(かも)
➡   1.2.x
    •   play pluginコマンドがある

    •   Pythonで作成
        - commands.py

➡   2.0.x
    •   sbtプラグインとして作成

    •   Scalaで作成

    •   プラグインのひな形を用意してみた
        - https://github.com/karad/play2-plugin-base
        - https://github.com/karad/play2-project-info


              Scalaの練習に良いのでどんどん書こう
                                                        32
デプロイ方法の違い




            33
フレームワークIDについて
➡   1.2.x
    •   play idコマンドでつける

    •   application.conf内でidごとに設定をまとめられた

➡   2.0.x
    •   framework idはない

    •   起動時に引数でconfを指定
        - $ start -Dconfig.resource=prod.conf

    •   hoge.confにて、
        - include "basic.conf"のように書ける
        - プロパティの上書きも可能


                         デプロイ方法は変更
                                               34
Play 2.0 for Play 1.x developers
➡   https://github.com/playframework/Play20/
    wiki/Play-2.0-for-Play-1.x-developers
    •   いろいろな細かなコードの変更箇所がまとめられています




                                               35
2.0.xの導入のしどころ
WebSocketを使用する場面
➡   Akkaによる非同期、イベント処理
➡   ChannelとMemberの作成が楽
➡   デフォルトでJSON




https://github.com/karad/PlayWebSocketReversi


                                                37
マルチデータベースを使用する場面
➡   1.2.xではマルチベータベースが使えない
    •   1.3で対応らしい? パッチはある

➡   2.0.xでは、Ebeanで対応している

    db.a.driver="com.mysql.jdbc.Driver"
    db.a.url="mysql://root:root@localhost/a"

    db.b.driver="com.mysql.jdbc.Driver"	
  
    db.b.url="mysql://root:root@localhost/b"

    ebean.a="models.a.Admin"
    ebean.a="models.b.Blog"


                                               38
今、1.2.5の使いどころは?
➡   スキルがまばらなメンバーのコラボレーション
    •   Eclipseプラグイン

➡   セッションを多用するWebアプリケーション
    •   2.0には、セッションIDがない

➡   ジョブが必要なWebアプリケーション
    •   1.2.xではデフォルトでJOBが内蔵

    •   2.0ではAkkaを使う事で実現が可能

➡   認証が必要なアプリケーション
    •   プラグインの追加が必要なため

➡   Webテストを行いたい場合
    •   2.0にはWeb画面で管理できるテストがない。欲しい!!
                                       39
Play 2.0 JavaとScala
➡   2.0のAPIをほじっていくと、Scalaのコードを
    見る羽目に
➡   Play 2.0 JavaもScalaぽい実装が多々ある
    •   F.javaとか

➡   プラグインをScalaで書いていく事でScalaの素養も
    身に付く
➡   Play 2.0が充実した頃(1年後とか)に正式導入も
    ありではないだろうか

                   仕事での導入は職場、案件次第

                                    40
応用編:1.2.xを2.0.xライクに使おう
Scalaテンプレート(ぽいのを使う)
➡   http://www.playframework.org/modules/
    rythm-1.0.0-RC4/home

    @extends(main)
    @args	
  List<User>	
  users
    <ul>
    @for(User	
  user:	
  users)	
  {
    	
  	
  	
  	
  @if	
  (!user.disabled())	
  {
    	
  	
  	
  	
  	
  	
  	
  	
  <li>
    	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  @user.getName()
    	
  	
  	
  	
  	
  	
  	
  	
  </li>
    	
  	
  	
  	
  }
    }
    </ul>

                                                                      42
Rythmの特徴 - その1
➡   Static and strong typed pure Java template.
➡   Razor like syntax
➡   Easy to integrate with Play and migrate your groovy template one by
    one

    •   Your existing controllers doesn t need to be changed

    •   Once an new template file under app/rythm folder created in the
        corresponding path, Rythm will take over; all other groovy
        templates still works

    •   Great Error reporting on parsing, compilation and excuting errors,
        using Play-2.0 style!
➡   Automatic escape expression output, like Groovy and unlike Japid
➡   High performance at Japid level




                                                                             43
Rythmの特徴 - その2
➡   Support layout and tag, you get all you have in Groovy template,
    actually even more
➡   (Play specific) Support FastTags and JavaExtensions with constraints
➡   (Play specific) Support properties enhancement to template class
➡   Template content decorations and chain them together
➡   (Play specific) Invoke controller action method directly from within
    your template

    •   @controllers.MyPortal.welcomePanel()
➡   Include other template inline (not the same as tag invocation)

    •   @include - @invoke("designer.mobile")

    •   @invoke - @invoke("designer." + platform)
➡   (Play specific) New Cache4 annotation to mark on controller action
    method
➡   (Play specific) Support GAE

                                                                          44
モデルをEbeanにする
➡   http://www.playframework.org/modules/
    ebean
    •   import play.db.jpa.Model;

    •   ではなく、

    •   import play.modules.ebean.Model;

➡   sampleフォルダ内に使い方のサンプルがある
    •   /ebean-yabe

    •   /ebean-zencontact




                                            45
すると、こうなる、1.2.x
➡   Controller
    •   そのまま

➡   View
    •   Razorライク(つまりPlay 2.0ライク)

➡   Model
    •   Ebean(Play 2.0 Javaライク)




                                   46
Controller
➡   コントローラーはなるべく薄く、必要な処理は、
    独立したJavaのクラスにしておくと移行が楽

Akka
➡   メンテされてないけどAkkaのモジュールもあるよ




                               47
ありがとうございました
PlayBayというハッカソンなどが
中心の勉強会をやってます

#playbay
@kara_d




                     48

Play framework 2.0のおすすめと1.2からのアップグレード

  • 1.
    Play 2.0 Javaのオススメと 1.2からのアップグレード 原 一浩 @kara_d
  • 2.
    原 一浩 @kara_d http://greative.jp/
  • 3.
    何してる人? Greative is Great Creative デザイントレンド、統計(R)、システム
  • 4.
    本日のアジェンダ ➡ まえがき:何故 2.0 Javaなのか? ➡ 基本編:1.2.x -> 2.0.x Javaへ ➡ コラム:2.0.xの導入のしどころ ➡ 応用編:1.2.xを2.0.xライクに使おう 4
  • 5.
  • 6.
  • 7.
    ビジネス要件にマッチ ➡ 受託制作をメインでやってます ➡ プレゼンの際にJavaベースで通せる • プログラム言語のプレゼンテーション ここ結構大変 • フレームワークのプレゼンテーション • プロジェクト自体のプレゼンテーション ➡ Javaのブランドの積み重ねはすごい ➡ Railsぽくスピーディに開発したい • 比較対象に、PHP、Rubyのフレームワークが入ってきたりする 7
  • 8.
    コラボレーション上の選択 ➡ 開発者人数の圧倒的な差(世界で900万人とも) ➡ 引き継ぎのしやすさ • クライアント社内でJavaのメンテが出来たりなど ➡ そもそもフリーで、Scalaできて、忙しくない人を あまりしらない(仲良くしてください^^) Javaの進化により、回帰するんじゃないか説 ➡ Java 7、Java 8は、モダンな仕組みも取り入れつつ よくなっていくぽい気がする ➡ Xtendとかもよかったりして 8
  • 9.
    Xtend ➡ 個人的な興味 • http://www.eclipse.org/xtend/ 9
  • 10.
    新しいことへは挑戦したいので ➡ 基本のアプリケーションは、2.0 Javaで開発 ➡ Scalaは、汎用のプラグインを作る際に使用し、 それをプロジェクトに導入 • 「弊社プラグインをライブラリとして採用してます」的な ➡ コンソール用のツールはsbtプラグインで作成 ➡ Scalaは、まだまだ勉強中 このへんはそれぞれの立場によりますね... 10
  • 11.
  • 12.
  • 13.
    Play 1.2.5本体のフォルダ構成 ➡ /documentation ➡ /framework ➡ /modules ➡ /python ➡ README.textile ➡ /resources ➡ /samples-and-tests ➡ /support 13
  • 14.
    1.2.xのEclipseプラグイン:Routes ➡ 最近、良さに気づきました(遅 14
  • 15.
    1.2.xのEclipseプラグイン:View ➡ Viewもバッチリ。2.0もSublimeTextにはプラグインあり 15
  • 16.
    1.2.xのEclipseプラグイン:Tools New Controller New View New Model Go Routes ショートカットがMVC!! 2.0版もはやく欲しい!! 16
  • 17.
    Play 2.0.x本体のフォルダ構成 ➡ /documentation • Play 2.0 Documentation.pdf 必須 ➡ /framework • src/play/src/main/java • src/play/src/main/scala ➡ README.md ➡ /repository ➡ /samples ➡ /support 17
  • 18.
  • 19.
    モデルの大幅な変更 ➡ 1.2.x • JPA拡張 • play.db.jpa.GenericModelクラスを継承したモデルを作る事で 下記を利用可能 - create()、find()、findAll()、save()、edit()、delete().... ➡ 2.0.x • Ebean ebeanEnabled := true/false • play.db.ebean.EbeanPluginクラスがある • play.db.ebean.Modelクラスを継承 • 1.2よりも薄いラッパー モデルは、書き直すか、JPAを利用 19
  • 20.
    Ebeanって ( Д)? ➡ Ebean is an open source (LGPL license) Java Object Relational Mapping tool. It uses JPA Annotations (@entity, @OneToMany ...) for mapping. ➡ メソッドチェーンでSQLぽく組み立てる Order  order  =  Ebean.find(Order.class)                    .select("orderDate")                    .where().idEq(12)                    .findUnique();     ➡ 既に豊富なドキュメントがある • http://www.avaje.org/doc/ebean-userguide.pdf 20
  • 21.
  • 22.
    コントローラーの考え方が変更 ➡ 1.2.x • render()、renderText()、renderHtml()、renderJson()... • アクションの返り値は、なし(void) ➡ 2.0.x • ok()、notFound()、internalServerError()、forbidden() • アクションの返り値は、Result型 HTTPプロトコルのレスポンスを再現 設定より規約 → 規約より型 大幅に書き換えが必要 22
  • 23.
    JSONの扱い ➡ 1.2.x • Gson - RenderJSON()などで使用 ➡ 2.0.x • Jackson(Scalaでは、Jerkson) - WebSocketなどで使用 JSONを使っている場合は修正 23
  • 24.
    認証周り ➡ 1.2.x • SECUREモジュールを使用(標準) ➡ 2.0.x • AuthenticityToken module for Play2!(後述) • play-authenticate - http://joscha.github.com/play-authenticate/ • Deadbolt2 - http://www.playframework.org/modules/deadbolt 複数のモジュールの組み合わせで対応 24
  • 25.
  • 26.
    一番変化が激しいビュー ➡ 1.2.x • GroovyTemplate • よくある${hoge}、#{hoge}、@{hoge}というスタイル • 複雑なタグはFastTagを使う ➡ 2.0.x • ScalaTemplate • Microsoft Razorライクなシンタックス • 最終的にはScalaの関数になる • 複雑なタグは単純にJavaのクラスで実装可能 全体的な修正、もしくは... 26
  • 27.
    Play 2.0でGroovy Template ➡ Groovy Template Engine for Play 2 • https://github.com/mbknor/gt-engine-play2/ • ほとんどのGroovyTemplateが使用可能 • FastTagも使用可能とのこと(試したところウマく動かず) ほぼ修正なしでいけるぽい 27
  • 28.
    Razorって? ( Д) ➡ @を利用してテンプレート式のブロックを示す ➡ @を使う場合は@@と記述 ➡ @以降は、Scala(本家はC#)コードに変換 ➡ @{}で複数行 ➡ 文中の{}も全てパースされる • つまり「{」が片方しか無いとエラー • play2-short-filter - https://github.com/karad/play2-short-filtr - @r("{")というかんじで使える 28
  • 29.
    CSRF対策 ➡ 1.2.x • 自動 ➡ 2.0.x • AuthenticityToken module for Play2! - https://github.com/orefalo/play2-authenticitytoken import  authtoken.validator.AuthenticityToken; @Entity   public  class  Page  extends  Model{        @Transient        @AuthenticityToken        public  String  authtoken; } 29
  • 30.
  • 31.
    モジュールのルートに関する考え方の違い ➡ 1.2.x • モジュールはroutesに定義 - GET / module:site • routesの入れ子が可能 - GET /? site.Site.index ➡ 2.0.x • パッケージの宣言による • フラットにroutesを管理できる印象 sbtプラグイン化が良い 31
  • 32.
    コンソールが作りやすくなった(かも) ➡ 1.2.x • play pluginコマンドがある • Pythonで作成 - commands.py ➡ 2.0.x • sbtプラグインとして作成 • Scalaで作成 • プラグインのひな形を用意してみた - https://github.com/karad/play2-plugin-base - https://github.com/karad/play2-project-info Scalaの練習に良いのでどんどん書こう 32
  • 33.
  • 34.
    フレームワークIDについて ➡ 1.2.x • play idコマンドでつける • application.conf内でidごとに設定をまとめられた ➡ 2.0.x • framework idはない • 起動時に引数でconfを指定 - $ start -Dconfig.resource=prod.conf • hoge.confにて、 - include "basic.conf"のように書ける - プロパティの上書きも可能 デプロイ方法は変更 34
  • 35.
    Play 2.0 forPlay 1.x developers ➡ https://github.com/playframework/Play20/ wiki/Play-2.0-for-Play-1.x-developers • いろいろな細かなコードの変更箇所がまとめられています 35
  • 36.
  • 37.
    WebSocketを使用する場面 ➡ Akkaによる非同期、イベント処理 ➡ ChannelとMemberの作成が楽 ➡ デフォルトでJSON https://github.com/karad/PlayWebSocketReversi 37
  • 38.
    マルチデータベースを使用する場面 ➡ 1.2.xではマルチベータベースが使えない • 1.3で対応らしい? パッチはある ➡ 2.0.xでは、Ebeanで対応している db.a.driver="com.mysql.jdbc.Driver" db.a.url="mysql://root:root@localhost/a" db.b.driver="com.mysql.jdbc.Driver"   db.b.url="mysql://root:root@localhost/b" ebean.a="models.a.Admin" ebean.a="models.b.Blog" 38
  • 39.
    今、1.2.5の使いどころは? ➡ スキルがまばらなメンバーのコラボレーション • Eclipseプラグイン ➡ セッションを多用するWebアプリケーション • 2.0には、セッションIDがない ➡ ジョブが必要なWebアプリケーション • 1.2.xではデフォルトでJOBが内蔵 • 2.0ではAkkaを使う事で実現が可能 ➡ 認証が必要なアプリケーション • プラグインの追加が必要なため ➡ Webテストを行いたい場合 • 2.0にはWeb画面で管理できるテストがない。欲しい!! 39
  • 40.
    Play 2.0 JavaとScala ➡ 2.0のAPIをほじっていくと、Scalaのコードを 見る羽目に ➡ Play 2.0 JavaもScalaぽい実装が多々ある • F.javaとか ➡ プラグインをScalaで書いていく事でScalaの素養も 身に付く ➡ Play 2.0が充実した頃(1年後とか)に正式導入も ありではないだろうか 仕事での導入は職場、案件次第 40
  • 41.
  • 42.
    Scalaテンプレート(ぽいのを使う) ➡ http://www.playframework.org/modules/ rythm-1.0.0-RC4/home @extends(main) @args  List<User>  users <ul> @for(User  user:  users)  {        @if  (!user.disabled())  {                <li>                        @user.getName()                </li>        } } </ul> 42
  • 43.
    Rythmの特徴 - その1 ➡ Static and strong typed pure Java template. ➡ Razor like syntax ➡ Easy to integrate with Play and migrate your groovy template one by one • Your existing controllers doesn t need to be changed • Once an new template file under app/rythm folder created in the corresponding path, Rythm will take over; all other groovy templates still works • Great Error reporting on parsing, compilation and excuting errors, using Play-2.0 style! ➡ Automatic escape expression output, like Groovy and unlike Japid ➡ High performance at Japid level 43
  • 44.
    Rythmの特徴 - その2 ➡ Support layout and tag, you get all you have in Groovy template, actually even more ➡ (Play specific) Support FastTags and JavaExtensions with constraints ➡ (Play specific) Support properties enhancement to template class ➡ Template content decorations and chain them together ➡ (Play specific) Invoke controller action method directly from within your template • @controllers.MyPortal.welcomePanel() ➡ Include other template inline (not the same as tag invocation) • @include - @invoke("designer.mobile") • @invoke - @invoke("designer." + platform) ➡ (Play specific) New Cache4 annotation to mark on controller action method ➡ (Play specific) Support GAE 44
  • 45.
    モデルをEbeanにする ➡ http://www.playframework.org/modules/ ebean • import play.db.jpa.Model; • ではなく、 • import play.modules.ebean.Model; ➡ sampleフォルダ内に使い方のサンプルがある • /ebean-yabe • /ebean-zencontact 45
  • 46.
    すると、こうなる、1.2.x ➡ Controller • そのまま ➡ View • Razorライク(つまりPlay 2.0ライク) ➡ Model • Ebean(Play 2.0 Javaライク) 46
  • 47.
    Controller ➡ コントローラーはなるべく薄く、必要な処理は、 独立したJavaのクラスにしておくと移行が楽 Akka ➡ メンテされてないけどAkkaのモジュールもあるよ 47
  • 48.