tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

【Mojolicious】Mojoliciousでconfig的なファイルを扱うメモ - Mojolicious::Plugin::Config

はじめに

タイトル通りですがMojoliciousアプリでConfig的なファイルを扱いたいなーと思ったときのメモです。
Mojolicious::Plugin::Configを使って実現します。

アジェンダ

  1. どんなもの?
  2. Mojolicious::Plugin::Configについて
  3. Mojolicious::Plugin::Configを使う
  4. 開発環境や本番でconfigを分ける
  5. Mojolicious::Plugin::Configを使ったMojoliciousアプリサンプル

1. どんなもの?

Mojoliciousアプリ内においた設定ファイル(今回はjson)ファイルを読み込んで
こんな感じに使えるようにします。

  • Index.pm
package Hoge::Web::Controller::Index;
use Mojo::Base 'Mojolicious::Controller';

# This action will render a template
sub index {
  my $self = shift;

  # configを使う
  my $WEB_CONF = $self->app->config->{WEB};
  my $DB_CONF  = $self->app->config->{DB};
}

2. Mojolicious::Plugin::Configについて

Mojolicious::Plugin::Configについてと言いつつもただリンクするだけにしておきます。
Mojolicious::Plugin::Config自体はmojoliciousをインストールした際にデフォルトでインストールされているらしいです。

3. Mojolicious::Plugin::Configを使う

概要

使うのは簡単で、
適当なディレクトリにファイル名.confのような(拡張子も何でもいい)を作成して
アプリの起動時にルートコントローラで読み込むようにします。

設定ファイルの置き場所

置き場所はどこでもいいのですが、
今回はmojoアプリ/etcというディレクトリを作ってそこに置くようにします。

雛形作成コマンド

下記のmojoコマンドでMojolicousアプリの雛形を作成した前提で話を進めます。

$ carton exec mojo generate app ConfigSample::Web
作成後のディレクトリ

そのときのディレクトリ構造はこんな感じ

$ pwd
/path/to/mojoliciousアプリディレクトリ

$ tree
.
├── lib
│   └── ConfigSample
│       ├── Web
│       │   └── Controller
│       │       └── Example.pm
│       └── Web.pm
├── public
│   └── index.html
├── script
│   └── config_sample_web
├── t
│   └── basic.t
└── templates
    ├── example
    │   └── welcome.html.ep
    └── layouts
        └── default.html.ep
config用ディレクトリとファイルを追加

/etcディレクトリと設定ファイルを作成します。
参考サイトにもなぞらえてますが、今回はetc/db.confetc/web.confという設定ファイルを作ってみました。

$ tree
.
├── etc
│   ├── db.conf
│   └── web.conf
├── lib
├── public
├── script
├── t
└── templates
ファイルの中身

ファイルの中身はそれぞれこんな感じ

  • etc/db.conf
{
    # WEBの設定
    WEB => {
        IMG_DIR => '/img',
        CSS_DIR => '/css',
    },
    ERROR => {
        PAGE => '',
        NO_PAGE_TEXT => 'It is under maintenance.',
    },
    
}
  • etc/web.conf
{
  # DBの設定
  DB => {
    DB_NAME => 'db_name',
    DB_USER => 'db_user_name',
    DB_PASS => 'db_password',
    DB_HOST => 'localhost',
    DB_PORT => '3306',
    MYSQL_SOCKET_PATH  => '/tmp/mysql.sock',
  },
}

読み込んでみる

今回の例でいうと、
script/config_sample_webを起動した際に読み込まれるルートコントローラの lib/ConfigSample/Web.pm`で設定ファイルを読み込みます。

  • lib/ConfigSample/Web.pm
package ConfigSample::Web;
use Mojo::Base 'Mojolicious';
use Path::Class;

# This method will run once at server start
sub startup {
  my $self = shift;

  # configを読み込む
  $self->_load_config()

  # Documentation browser under "/perldoc"
  $self->plugin('PODRenderer');

  # Router
  my $r = $self->routes;

  # Normal route to controller
  $r->get('/')->to('example#welcome');
}

# configを読み込むやつ
sub _load_config {
  my $self = shift;

  my $home = new Path::Class::File(__FILE__);
  my $root = $home->dir->resolve->absolute->parent->parent();
  for my $e ( qw/web db/ ) {
    my $f = $root->stringify . '/etc/' . $e . '.conf';

    # Mojolicious::Plugin::Configを使ってconfigを読み込んでいる場所
    $self->plugin( 'Config', { 'file' => $f } );
  }
}

すると各コントローラで$self->appを通してconfigが使えるようになります。

my $WEB_CONF = $self->app->config->{WEB};
my $DB_CONF  = $self->app->config->{DB};

warn $WEB_CONF->{IMG_DIR}; # '/img'

4. 開発環境や本番でconfigを分ける

これは自分がお手軽にやってるだけのあくまでも一例です。

MOJO_MODE

MojoliciousにはMOJO_MODEという環境変数が使えるのでそれを利用します。
アプリケーションの中ではこんな感じで取得します。

$self->app->mode;

環境変数を何も指定してない場合のデフォルトはdevelopmentという文字列が設定されています。

これをmorboなりplackupなりで起動する際に
MOJO_MODEを指定してあげることで開発環境と本番環境を分けてみます。

本番環境ではこんな感じで起動してあげることでMOJO_MODEがproductionになります。

$ MOJO_MODE=production morbo script/myapp

環境ごとに設定ファイルを分けてみる

ってことで、etcディレクトリ以下のファイル名をこんな感じで用意します。

設定ファイル
  • etc/web_dev.conf
  • etc/web_prd.conf
  • etc/db_dev.conf
  • etc/db_prd.conf
読み込み

ルートコントローラでの読み込みをこんな感じに変えます。

~ 省略 ~
# configを読み込むやつ

sub _load_config {
  my $self = shift;
  my $home = new Path::Class::File(__FILE__);
  my $root = $home->dir->resolve->absolute->parent->parent();

  # 環境によってsuffixを分ける
  my $suffix = $self->mode eq 'production' ? '_prd' : '_dev';
  for my $e ( qw/web db/ ) {
    my $f = $root->stringify . '/etc/' . $e . $suffix . '.conf';
    $self->plugin( 'Config', { 'file' => $f } );
  }
}

5. Mojolicious::Plugin::Configを使ったMojoliciousアプリサンプル

今回と同じ構成のMojoliciousアプリのサンプルをgithubにおいてあります。
README.mdに使い方も載せてあるのでよかったらどーぞ。

まとめ

ってことでMojoliciousアプリでのconfigの使い方でした。
Mojoはいろいろ用意ががいいので使い勝手がいいです!