Blog

Typesafe Configを使って環境設定を切り替えしてみる


こんにちは。DynalystのHanです。Dynalystではアプリケーションの設定にTypesafe Configを使っています。

そこでProductionやテスト環境毎にアプリケーション設定をどう切り替えてるのかについて簡単に紹介したいと思います。

Typesafe Configを選んだ理由

Scalaをやる前まではJavaエンジニアだったのでアプリケーションの設定ファイルなら何も考えず.propertiesに定義するのは定番だけど、せっかくScalaをやり始めてるのでScalaの開発ではどのライブラリがよく使われているのかを調べていました。

そこで発見したのがTypesafe Configです。

  • .propertiesも勿論対応してますし、ResourceBundleより便利な機能がたくさんある。
  • そしてAkka, Play, Slick, SprayなどScalaでは有名なOpenSource Projectにもよく使われている。
  • HOCONが見やすい
  • あとはTypesafeという安定なネームバリュー!

Typesafe ConfigのソースコードはJavaで書かれています。

Typesafe Configの使い方

Typesafe Configの基本的な使い方やRuntime時の動き方は公式レポジトリのREADME.mdに詳しく書いてあります。

たとえば、以下のような設定ファイルがあった場合にConfigオブジエクトから値を取得することができます。

値はシステム環境変数から取得することもできます。たとえばSCALA_HOMEといったシステム環境変数があるとしたら

また、別ファイルに定義されている設定をincludeして使うこともできます。

ここでincludeするときにclasspathというメッソドにinclude先のファイル名を渡していたのでこれを拡張もしくはあるinterfaceを実装すれば環境毎設定ファイルを読ませることができてそれぞれの値で置換できるんじゃないかと思い、ソースコードをみたところConfigIncluderというinterfaceと実装クラス発見!

Environment Protocolを定義して環境設定切り替え

urlからも設定ファイルがincludeできるのが分かったのでRuntimeの時にどの環境で実行されてるかを
認知できるcustom protocolを定義して以下のように書けることができます。

Environment Protocol定義

custom protocolを定義するには以下のinterfaceを実装してJVMがそのprotocolを認識できるように設定する必要があります。

動作確認

これでそれぞれ環境を引数でsbt runすると

環境毎に値を取得することができました!

LGTM

まとめ

アプリケーション設定をしていた時にapplication.confの中身が${database.url}なっていてあまり直感的なじゃないというのとテストのためにもCustom Protocolを設定しないといけないのはデメリットかもしれません。

Dynalystではテストにspecs2を使っていてテスト環境用の値が取得されるようにtrait EnvResolvedSpecificationをよいしています。

またサーバーやバッチにはtrait EnvironmentProtocolResolverをよいしてmainクラスにmix-inして使ってます。

本文で使っていた例はGithubに公開されているので違うやりかたで環境設定を解決している方は是非教えてください!

Author

アバター
sangwon