##テスト環境と本番環境
実際のシステム開発を行っていると「テスト環境」と「本番環境」でデータベースやWeb APIの接続先が異なることは良くあります。
もちろん、テスト環境や本番環境だけに限らずローカル開発環境の場合もあるでしょうし、同じテスト環境で同じアプリケーションでも(何かの都合で)接続先を変えることがあったりします。
そのような場合、どうやって接続先を設定するのがいいのでしょうか。
以下、Javaを想定して記述しますが多くの言語に当てはまる内容だと思います。
##接続先を変える様々な方法
###方法1 ソースべた書き都度ビルド
ソースコード中にベタで接続先を記述し、環境ごとにソースを修正、ビルドを行う方法です。
論外です。
###方法2 設定ファイルに設定都度ビルド
ソースコードに直接記述するのでなく、プロパティファイルのような設定ファイルに接続先を記述し、環境ごとにその設定ファイルを修正しビルドを行う方法です。
本質的に方法1と何ら変わらないのでやはり論外としたいのですが、この方法を選択しようとする人が結構いることも事実です。
###方法3 設定モジュール外の設定ファイルに配置
プロパティファイルに記述という点では方法2と同じなのですが、ビルド対象のリソースには含めずアプリからアクセスできるどこかに置いておくというものです。
接続先によってビルドしなおさなくても良いという点では方法1、2よりも良さそうですが、設定ファイルのアクセス先(ファイルのパスなど)に依存した実装になるというのと、AWS Lambdaのようなサーバレスには適用しにくいという問題もあります。
###方法4 設定環境ごとの設定ファイルを作成
例えばファイル名の末尾に test
や prod
などをつけて起動引数などで環境指定してどのファイルを適用するか切り替えるというものです。
都度ビルドはいらないのですが、接続先の数だけファイルを用意したり環境名を意識したファイル名にしたりと割と煩わしいです。
Seasar2が env.txt
を使ってこの方法をサポートしていたので、この方法を適用しているプロジェクトは多いのではないでしょうか。
###方向5 環境変数で設定
接続先自体を環境変数として設定し、アプリケーションでは環境変数から取得するように実装します。
Springが @Value("${env.name}")
のような感じでサポートしているのでこの方法も利用している人が多いかもしれません。
##ベストプラクティスは?
ここで この方法が一番! って言い切れればいいのですが、私もまだ模索中です。
色んな知見をコメントでいただけると嬉しいです。
今までは方法4が多かったのですが、最近は方法5を適用するようにしています。
理由の一つは 環境ごとに変わる値をモジュール内に持ちたくない というものです。環境ごとに値が変わるのならそれはアプリケーションのリソースとして管理するのではなく環境そのもので管理したいということです。
それと最近よく利用するAWSのLambdaやECSなどと相性がいいというのもあります。
LamddaやECSタスクの定義に環境変数を設定できるので、環境ごとのLambdaやECSタスクを定義すればいいというのも手軽でわかりやすいです。
上にも書きましたがSpringで簡単に環境変数の値を変数に設定できるのも便利です。
スレッドの生成数などのようにアプリケーションの動作に影響を及ぼすものはプロパティファイルでもいいような気がしますが、アプリケーションの振る舞いを一切変えない(そして環境ごとに値が変わる)接続先のような情報は環境変数に設定するのがいいのではないでしょうか。
以上、環境ごとに違う接続先の設定方法についてでした。