Configプラグインで使うJSON形式の外部設定ファイル

# Configプラグインで使うJSON形式の外部設定ファイル

この前[Configプラグインで使う実用的な外部設定ファイルの一例](http://qiita.com/azumakuniyuki/items/2fcec597335d5fd011e5)を書いた[@azumakuniyuki](https://twitter.com/azumakuniyuki)です。

Mojoliciousで外部設定ファイルを使う方法は、僕が書いた方法以外にも[ゆーすけべーさん](https://twitter.com/yusukebe)が書かれた[250万ダウンロードアプリを支えるBokete.pmを覗く](http://qiita.com/yusukebe/items/c4d67b49f1deac5a4a80)のような自前で実装する方法もあります。

これらの記事で紹介されている設定ファイルは、Perlの文法にしたがって記述する設定ファイルです。今日はPerl以外の文法で書ける外部設定ファイルのプラグインを紹介することにします。


## Mojolicious::Plugin::JSONConfig

[Mojolicious::Plugin::JSONConfig](http://mojolicio.us/perldoc/Mojolicious/Plugin/JSONConfig)はプラグインの名称どおり、JSONで記述した設定ファイルを読込めるプラグインです。このプラグインは最初からMojoliciousに含まれているので、追加でインストールする事なく使えます。

### JSONの設定ファイルを準備する

12月10日に書いた[Configプラグインで使う実用的な外部設定ファイルの一例](http://qiita.com/azumakuniyuki/items/2fcec597335d5fd011e5)で出てきた二つの設定ファイル、`etc/neko.conf`と`etc/auth.conf`をJSONで書き直すと、以下のような感じになります。

```json:etc/neko.json
{
    "site":  {
        "maintenance": 0,
        "copyright": "Copyright (C) 京都市役所ネコ課",
        "ja": {
            "name": "ネコの管理システム"
        },
        "en": {
            "name": "Stray Cats Administration System"
        }
    }
}
```

```json:etc/auth.json
{
    "database": {
        "dbtype": "MySQL",
        "dbname": "nekochan",
        "hostname": "192.0.2.222",
        "port": 3306,
        "username": "dbadmin",
        "passowrd": "nyanko"
    }
}
```

これまでPerlで書いていた設定ファイルをJSONで書き直した内容が上記になります。書き換えについては次の点に注意しないと、`Malformed JSON`とエラーが表示されます。

* キー名を `"名前"` な感じで囲む
* `=>` を `:` に変える
* 最後の値の後に`,`(所謂ケツカンマ)は書けない(例えば`"password": "nyanko",`はエラーとなる)
* コメントは書けない

各値を改行で区切って列挙出来るのは良いですし、`:`で区切るのも設定ファイルっぽくて分かりやすいですが、コメントが書けないのが残念なところです。

## lib/Noraneko/Web.pm

JSONConfigプラグインを使う場合は、プラグインの読込み部分のコードを少し変えるだけでOKです。

12月11日の記事、[設定ファイルがない場合の代替手段と簡易メンテページ](http://qiita.com/azumakuniyuki/items/23cc6b090fc72cc0eb10)で作ったコードをJSON用に変えてみた差分が下記の内容です。

```diff:/Noraneko/Web.pm
diff --git a/lib/Noraneko/Web.pm b/lib/Noraneko/Web.pm
index 5eeed45..97351fc 100644
--- a/lib/Noraneko/Web.pm
+++ b/lib/Noraneko/Web.pm
@@ -11,13 +11,14 @@ sub startup {
     my $fail = 0;
 
     for my $e ( 'neko', 'auth' ) {
-        my $f = $root->stringify.'/etc/'.$e.'.conf';
+        my $f = $root->stringify.'/etc/'.$e.'.json';
 
         eval {
-            $conf->{ $e } = $self->plugin( 'Config', { 'file' => $f } );
+            $conf->{ $e } = $self->plugin( 'JSONConfig', { 'file' => $f } );
         };
         $conf->{ $e } ||= Noraneko::Config->$e;
         $fail = 1 if $@;
     }
```

読込むファイルの拡張子とプラグインの名前を変えた二箇所が差分です。

## Mojolicious::Plugin::YmlConfig

もう一つの手段がYAML形式の設定ファイルが使えるようになる`Mojolicious::Plugin::YmlConfig`というプラグインです。JSONのそれとは異なり、これはMojoliciousには含まれていないプラグインですので、使う場合は自分で入れる必要があります。

```
% sudo cpanm Mojolicious::Plugin::YmlConfig
--> Working on Mojolicious::Plugin::YmlConfig
...
結構長い
...
```

ただ、このプラグインは`Mojolicious::Plugin::Bundle`というプラグインのセットに含まれる物で、[依存するモジュールがかなり多く](http://deps.cpantesters.org/?module=Mojolicious::Plugin::Bundle) **あんまりお勧めではありません。**

設定ファイルにYAMLを使いたい場合は、[YAML](https://metacpan.org/pod/YAML)モジュールを使って自前でローダを実装する方が良さそうです。

## github

一応、ちゃんと動くか心配なのでここで説明している箇所だけ実装したネコの管理アプリを更新してgithubに置いてきました。

[github.com/azumakuniyuki/Noraneko-Mojo-Sample](https://github.com/azumakuniyuki/Noraneko-Mojo-Sample)

## まとめ

Perlを知らない人が設定ファイルを書き換えるようなケースでは、JSONで書ける方が親しみやすいというのがあるかもしれません。そのような場合はJSONConfigプラグインを使うと良いでしょう。

しかし、JSONConfigプラグインで読込むJSONの設定ファイルにはコメントが書けませんし、所謂ケツカンマも認められていません。そもそもJSON自体、人間が手書きするものではないという意見もありますので、一長一短ではあります。

Perl以外の文法で設定ファイルを記述したい場合の最善の方法の一つは、YAMLかもしれません。JSONとYAMLは名前こそ全く違いますが、JSONをYAMLのサブセットとして見なす事が出来るので、記述後の見た目はよく似ています。別の表現をすればYAMLに制約を加えたものがJSONである、JSONから多少の厳格さを取り除いたものがYAMLである、といったところでしょうか。

話がMojoliciousから少しそれるのですが、僕が今年の夏ごろに書いた[Haineko](https://github.com/azumakuniyuki/Haineko)というメール送信用HTTPサーバがありまして、そこでは[設定ファイル](https://github.com/azumakuniyuki/Haineko/blob/master/etc/haineko.cf-example)をJSON(と言いながらYAMLとして評価している)で記述していて、設定ファイルにコメントを書く事が出来ますので、厳密なJSONよりは記述しやすいと思います。

なので、設定ファイルのローダを自前で実装するというのも充分有効な選択肢であると言えるでしょう。

## 参考

- [Mojolicious::Plugin::JSONConfig](http://mojolicio.us/perldoc/Mojolicious/Plugin/JSONConfig)
- [Mojolicious::Plugin::YmlConfig](https://metacpan.org/pod/Mojolicious::Plugin::YmlConfig)
- [Rubyist Magazine - プログラマーのための YAML 入門 (初級編)](http://magazine.rubyist.net/?0009-YAML)
- [JavaScript Object Notation - Wikipedia](http://ja.wikipedia.org/wiki/JavaScript_Object_Notation)
- 今日も参考ネコ画像はありません