Help us understand the problem. What is going on with this article?

Configプラグインで使う実用的な外部設定ファイルの一例

More than 5 years have passed since last update.

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のハッシュリファレンス で記述します。書く内容は滅多に変化しないであろう値や固定値を入れておくと良さそうです。

etc/neko.conf
{
    # サイト全体の設定
    site => {
        maintenance => 0,   # 1にするとメンテモードに移行するとか?
        copyright => 'Copyright (C) 京都市役所ネコ課',
        ja  => {
            name => 'ネコ管理システム',
        },
        en => {
            name => 'Stray Cats Administration System',
        },
    },
}

データベース接続情報とか認証関係の設定値はパーミッションを厳しくした別のファイルに書きます。

etc/auth.conf
{
    # データベースに関する設定
    'database' => {
        'dbtype' => 'PostgreSQL',
        'dbname' => 'nekochan',
        'hostname' => '192.0.2.22',
        'port' => 5432,
        'username' => 'dbadmin',
        'passowrd' => 'nyanko',
    },
}

この記事ではDB接続情報や外部サービスとの連携APIキー等、秘匿すべき情報はソースコードから分離して設定ファイルに入れる、またはそういった認証情報のみを保存した設定ファイルをもう一個作って、ファイルのパーミッションで制限する事にしています。

Noraneko::Webで設定ファイルを読込む

lib/Noraneko/Web.pm
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.confetc/auth.confConfigプラグインのメソッドで読込んでいます。読込んだ設定ファイルの内容は$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にある(というか自分で作る)レイアウトに埋め込んでしまえば良いのですが、例えばテンプレートに出さない処理結果にサイト名を入れたい(外部サービスに送るデータにサイト名を入れるとか)用途があるなら、コントローラ側でサイト名が参照出来る方が好都合です。

lib/Noraneko/Web/User/Root.pm
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要素を作っています。

templates/ja/user/root/index.html.ep
% 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/以下のソースコードに直接値を埋め込まないので、例えばデザイナーさんとかサイト管理者がソースコードを触らずともある程度の設定変更が出来るという点でしょうか。

この記事で作る事にしているシステムでは、例えばネコが欲しい人向けに管理しているネコの写真を表示するページがあったとして、一ページに表示するネコの数を設定ファイルで定義しておけばページ上のネコ表示数増減も容易です。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away