Configプラグインで使う実用的な外部設定ファイルの一例
この前Liteでないアプリの実用的なディレクトリ構造一例を書いた@azumakuniyukiです。
Advent Calendarの例示用にリポジトリを作ったので、もう少しネタが絞り出せそうな気がするので、構築するWebアプリケーションで外部設定ファイルを使えるようにする話を書きます。
Mojolicious::Plugin::Config
Mojoliciousをインストールすると、それに含まれるMojolicious::Plugin::Configを使うと簡単に外部設定ファイルを使う事が出来ます。勿論、プラグインを使わず自前で読込むコードを書いても外部設定ファイルは使えますが、Mojoliciousに標準で含まれているので、このプラグインを使う方が便利で合理的です。
設定ファイルを準備する
12月6日に書いたネコ管理アプリケーションの話の続きで、設定ファイルを追加する事にします。万が一手元で動かしてみたいとか、この記事に書いてる内容がほんまに動くのか確認したいって方は適当なディレクトリで git clone
して morbo script/noraneko_web
して下さい。
サンプルのソースを動かす
% git clone https://github.com/azumakuniyuki/Noraneko-Mojo-Sample.git
Cloning into 'Noraneko-Mojo-Sample'...
remote: Counting objects: 69, done.
remote: Compressing objects: 100% (54/54), done.
remote: Total 69 (delta 2), reused 69 (delta 2)
Unpacking objects: 100% (69/69), done.
Checking connectivity... done
% cd ./Noraneko-Mojo-Sample
% morbo script/norabeko_web
Server available at http://127.0.0.1:3000.
設定ファイルのディレクトリと空ファイル作成
以降、リポジトリの中に居るという前提で話が進みます。
% ls .
README.md
etc/
lib/
log/
public/
script/
t/
templates/
% mkdir ./etc
% touch ./etc/neko.conf
% touch ./etc/auth.conf
adminがデプロイするユーザ、appserverがサーバを動かすユーザ
% chown admin:appserver ./etc/auth.conf
% chmod o-rwx ./etc/auth.conf
設定ファイルを入れるディレクトリはetc
でもconf
でも何でも良いですが、僕はいつもetc
にしています。また設定ファイルの名前も何でも良いですし、拡張子も何でも良いです。
設定ファイルの内容
設定ファイルは Perlのハッシュリファレンス で記述します。書く内容は滅多に変化しないであろう値や固定値を入れておくと良さそうです。
{
# サイト全体の設定
site => {
maintenance => 0, # 1にするとメンテモードに移行するとか?
copyright => 'Copyright (C) 京都市役所ネコ課',
ja => {
name => 'ネコ管理システム',
},
en => {
name => 'Stray Cats Administration System',
},
},
}
データベース接続情報とか認証関係の設定値はパーミッションを厳しくした別のファイルに書きます。
{
# データベースに関する設定
'database' => {
'dbtype' => 'PostgreSQL',
'dbname' => 'nekochan',
'hostname' => '192.0.2.22',
'port' => 5432,
'username' => 'dbadmin',
'passowrd' => 'nyanko',
},
}
この記事ではDB接続情報や外部サービスとの連携APIキー等、秘匿すべき情報はソースコードから分離して設定ファイルに入れる、またはそういった認証情報のみを保存した設定ファイルをもう一個作って、ファイルのパーミッションで制限する事にしています。
Noraneko::Webで設定ファイルを読込む
package Noraneko::Web;
use Mojo::Base 'Mojolicious';
use Path::Class;
sub startup {
my $self = shift;
my $home = new Path::Class::File(__FILE__);
my $root = $home->dir->resolve->absolute->parent->parent();
for my $e ( 'neko', 'auth' ) {
my $f = $root->stringify.'/etc/'.$e.'.conf';
$self->plugin( 'Config', { 'file' => $f } );
# 適当な変数に受けとってもよい
# $conf = $self->plugin( 'Config', { 'file' => $f } );
}
my $r = $self->routes;
# この前書いたルーティングの設定とかいろいろ続く...
作った設定ファイルetc/neko.conf
とetc/auth.conf
をConfig
プラグインのメソッドで読込んでいます。読込んだ設定ファイルの内容は$self->defaults->{'config'}
でアクセス出来ます。
warn Dumper $self->defaults->{'config'};
$VAR1 = {
'database' => {
'dbtype' => 'PostgreSQL',
'hostname' => '192.0.2.22',
'port' => 5432,
'passowrd' => 'nyanko',
'username' => 'dbadmin',
'dbname' => 'nekochan'
},
'site' => {
'maintenance' => 0,
'en' => {
'name' => 'Stray Cats Administration System',
},
'ja' => {
'name' => "\x{30cd}\x{30b3}\x{7ba1}\x{7406}\x{30b7}\x{30b9}\x{30c6}\x{30e0}"
},
'copyright' => "Copyright (C) \x{4eac}\x{90fd}\x{5e02}\x{5f79}\x{6240}\x{30cd}\x{30b3}\x{8ab2}"
}
};
コントローラで設定値を使う
ここで例示しているのは、言語別にサイト名を定義している部分とDBへの接続情報です。
サイト名なんかは設定ファイルに書かず、直接テンプレートファイルやtemplates/layout
にある(というか自分で作る)レイアウトに埋め込んでしまえば良いのですが、例えばテンプレートに出さない処理結果にサイト名を入れたい(外部サービスに送るデータにサイト名を入れるとか)用途があるなら、コントローラ側でサイト名が参照出来る方が好都合です。
sub index {
my $self = shift;
my $lang = $self->stash('lang');
$self->stash( 'v' => $self->app->config->{'site'}->{ $lang } );
return $self->render( 'template' => $lang.'/user/root/index' );
}
テンプレートに渡す変数をv
という名前でstash
に入れています。ここでv
に入れた内容はテンプレート側で$v
として参照出来ますので、例えば以下で例示するテンプレートファイルではページ名 | サイト名
のような形でHTMLのtitle
要素を作っています。
% layout 'ja/user/default';
% title '市民のページ | '.$v->{'name'};
<h1>ニャー?</h1>
レイアウトについては本Advent Calendarの12月4日の記事、Mojoliciousのテンプレートでレイアウトを自在に操るに詳しく載っています。
github
一応、ちゃんと動くか心配なのでここで説明している箇所だけ実装したネコの管理アプリを更新してgithubに置いてきました。
github.com/azumakuniyuki/Noraneko-Mojo-Sample
まとめ
滅多に変更しないような固定値は外部設定ファイルに分離しておく方が管理がしやすいと思います。DBに設定テーブルを作るのもありやと思いますが、サーバが一台だけの小規模な構成であるなら、複数のサーバ間で設定値を共有する事も特に考えなくて良いですし設定ファイルを設置するという手段も充分有効です。
また、サーバを触るエンジニアだけがDB接続情報を参照出来るようにする、という運用を行う場合は、設定ファイルを複数用意してUNIXのユーザでのパーミッションを設定するという古典的な手法も充分有効です。
設定ファイルに分離する利点としては、lib/以下のソースコードに直接値を埋め込まないので、例えばデザイナーさんとかサイト管理者がソースコードを触らずともある程度の設定変更が出来るという点でしょうか。
この記事で作る事にしているシステムでは、例えばネコが欲しい人向けに管理しているネコの写真を表示するページがあったとして、一ページに表示するネコの数を設定ファイルで定義しておけばページ上のネコ表示数増減も容易です。
参考
- Mojolicious::Plugin::Config
- Mojoliciousのテンプレートでレイアウトを自在に操る
- 今日は参考ネコ画像はありません