実務での開発においては、ほとんどの場合、環境情報など変動しうる設定値を外部ファイルに記述しておく必要があります。
Goでは、設定ファイルを取り扱うための便利な外部ライブラリが豊富に存在します。
しかし、外部ライブラリを使用せず標準機能だけで設定ファイルを取り扱うことももちろん可能です。
本記事では、jsonパッケージを使用することで、外部ライブラリに依存せずにJSON形式の設定ファイルの作成・利用方法を紹介したいと思います。
設定ファイルのパッケージを作成する
設定ファイルを実装する場合、メンテナンスしやすいように、設定ファイルの取り扱い専用の独立したパッケージにしておくのが良いでしょう。
ここでは、設定ファイル用にconfという名称のパッケージを実装することにします。
goプログラムのフォルダに、confディレクトリを作成してください。
作成したconfディレクトリには、設定値を記述するjsonファイルと、jsonファイルを読み込むgoファイルを対にして配置します。
たとえば以下のような構成です。
|― conf/
|― db.json
|― db.go
|― session.json
|― session.go
|― url.json
|― url.go
・
・
・
|― main.go
この例では、db.jsonにデータベース関連の設定値を記述し、db.goにdb.jsonの内容を読み込むためのプログラムを記述します。
同様に、session.jsonとsession.goでセッション関連の設定を、url.jsonとurl.goでURL関連の設定を、といった具合です。
なお、ここではデータベース設定やURL設定など設定の種類ごとにファイルを分けることを想定していますが、一つのファイルにすべての設定をまとめて記述しても構いません。
メンテナンスのしやすさや設定値の用途などに応じて設計してください。
設定ファイルの内容
設定ファイルとなるjsonファイルには、JSON形式で必要な設定を列挙するだけです。
データベース設定の例を見てみましょう。
{ "host": "hoge-host", "port": 3306, "db-name": "hoge-db", "user": "hogehoge", "pass": "fugafuga" }
必要であれば、先頭のキーを”#comment”などとし、設定値の内容に関する説明を記述してもよいでしょう。
なお、実際にはパスワードなど暗号化する必要がありますが、ここでは省略します。
設定ファイルを読み込むgoプログラム
次に、設定ファイルを読み込むためのプログラムを見てみましょう。
このファイル内で行うことは以下の2点です。
- 設定ファイルを格納する構造体を定義する
- 設定ファイルを読み込み、値を構造体にセットする関数を記述する
それではサンプルを見てみましょう。
package conf // 独自の設定ファイルパッケージ import ( "encoding/json" "io/ioutil" ) // DB設定の構造体 type ConfDB struct { Host string `json:"host"` // ホスト名 Port int `json:"port"` // ポート番号 DbName string `json:"db-name"` // 接続先DB名 User string `json:"user"` // 接続ユーザ名 Pass string `json:"pass"` // 接続パスワード } // DB設定読み込み関数 func ReadConfDB() (*ConfDB, error) { // 設定ファイル名 const conffile = "conf/db.json" // 構造体を初期化 conf := new(ConfDB) // 設定ファイルを読み込む cValue, err := ioutil.ReadFile(conffile) if err != nil { return conf, err } // 読み込んだjson文字列をデコードし構造体にマッピング err = json.Unmarshal([]byte(cValue), conf) if err != nil { return conf, err } return conf, nil }
1行目のパッケージ名をconfにしている点に注目してください。
後にmainパッケージから設定ファイルの読み込みを行う際、このパッケージをインポートすることになります。
このパッケージ名は、ファイルを格納するディレクトリ名と一致させる必要があります。
構造体の名称とフィールド名、および関数名は、外部パッケージから参照可能にするため先頭を大文字にします。
関数内の処理は単純で、対となるjsonファイルを読み込み、読み込んだJSON文字列をデコードして構造体にマッピングしています。
これらの処理については以下の記事で解説していますので必要に応じてご参照ください。
【Go入門】構造体のフィールド定義、値、メタ情報を取得して列挙する
すべての処理が正常に完了したら、読み込み結果をマッピングした構造体と、error値にnilを返します。
メイン処理から設定ファイルを利用する
package main import ( "fmt" "strconv" "./conf" // 実装した設定ファイルパッケージの読み込み ) func main() { // 設定ファイルを読み込む confDB, err := conf.ReadConfDB() if err != nil { fmt.Println(err.Error()) } fmt.Println("取得した設定内容を出力します") fmt.Println("ホスト名: " + confDB.Host) fmt.Println("ポート: " + strconv.Itoa(confDB.Port)) fmt.Println("接続先DB名: " + confDB.DbName) fmt.Println("接続ユーザ名: " + confDB.User) fmt.Println("パスワード: " + confDB.Pass) }
import部で、作成したconfパッケージを読み込んでいます。
後は、利用したい設定に応じた関数を実行するだけで、JSON設定ファイルに記述した設定値を使用することができます。
さっそくmain.goを実行してみてください。
以下の通り、設定ファイルの内容がきちんと出力されるはずです。
ホスト名: hoge-host
ポート: 3306
接続先DB名: hoge-db
接続ユーザ名: hogehoge
パスワード: fugafuga
終わりに
Goにおいて標準機能だけで設定ファイルを実装する場合、今回紹介したJSON形式での実装がベターかと思います。
設定値がさほど多くなければ、この形式でメンテナンス性にも問題は生じないでしょう。
設定値が多くなり、設定項目をより細分化したくなった場合には、この方法では不便を感じるかもしれません。
その場合は、外部パッケージの利用などを検討してみてください。