LoginSignup
9
12

More than 5 years have passed since last update.

Golang + TOML で環境ごとに異なる設定を扱う

Posted at

TOML について

TOML の簡単な解説

  • 以下の TOML と JSON がだいたい一緒
int1 = 1
float1 = 0.1
bool1 = true
string1 = "string 1"
array1 = [1, 2, 3]

[table1]
col1 = "col 1"

[table1.subtable1]
col2 = "col 2"

[[tables]]
col3 = "col 3a"

[[tables]]
col3 = "col 3b"
{
    "int1": 1,
    "float1": 0.1,
    "bool1": true,
    "string1": "string 1",
    "array": [1, 2, 3],
    "table1": {
        "col1": "col 1",
        "subtable1": {
            "col2": "col 2"
        }
    },
    "tables": [
        {
            "col3": "col 3a"
        },
        {
            "col3": "col 3b"
        },
    ]
}
  • 基本の型として Integer, Float, Boolean, String, Datetime が扱える
  • Array は [ ] にいれてカンマ区切りでインラインでも複数ラインでも扱える
  • Table は [TABLE_NAME] として定義したら次のテーブルかファイル末尾までの要素が TABLE_NAME テーブルに入る
  • [TABLE_NAME.SUB_TABLE_NAME] でテーブルをネストできる
  • [[ARRAY_OF_TABLE_NAME]] でテーブルの配列が宣言できる

Golang で TOML を扱う

  • 公式のREADME に各言語ごとのパーサーへのリンクがある
  • Golang で最新バージョンに対応しているものだと github.com/naoina/toml が一番扱いやすそう

Golang + TOML で環境ごとに異なる設定を扱う

  • Rails とかの設定みたいにデフォルトの値と各環境ごとの値を定義しておいてマージして扱いたい
  • github.com/naoina/toml でデフォルト設定の構造体と環境ごとの設定の構造体を作ってマージするとかやりたかったが、環境ごと構造体のフィールドがゼロ値の場合に、設定されていないのかゼロ値が明示的に定義されているのかが判別できず目論見が失敗した
  • なので自分でいい感じにしてくれる github.com/nirasan/environment-toml を作ってみた

environment-toml 概要

  • environment-toml はファイルのパスと実行環境名を渡すことで TOML ファイルを読み込み設定用の構造体にセットする
  • キー名 key の値を読み込む場合 実行環境名.key が定義されていればそちらで上書きされる

例1. 基本型の値を環境ごとに上書きする

TOML ファイル

config.toml
username = "user"
password = "pass"

[development]
username = "root"

[production]
password = "toolongpassword"

読み込み実行

import "github.com/nirasan/environment-toml"

type Config struct {
    Username string
    Password string
}

// 実行環境が development の場合
c := &Config{}
toml.Load(c, "config.toml", "development")
fmt.Println(c.Username) //=> root | development.username に上書きされている
fmt.Println(c.Password) //=> pass | password そのまま

// 実行環境が production の場合
c = &Config{}
toml.Load(c, "config.toml", "production")
fmt.Println(c.Username) //=> user            | username そのまま
fmt.Println(c.Password) //=> toolongpassword | production.password に上書きされている

例2. Table のフィールドの値を環境ごとに上書きする

TOML ファイル

config.toml
[database]
username = "user"
password = "pass"

[database.development]
username = "root"

[database.production]
password = "toolongpassword"

読み込み実行

import "github.com/nirasan/environment-toml"

type Database struct {
    Username string
    Password string
}

type Config struct {
    Database Database
}

// 実行環境が development の場合
c := &Config{}
toml.Load(c, "config.toml", "development")
fmt.Println(c.Database.Username) //=> root | database.development.username に上書きされている
fmt.Println(c.Database.Password) //=> pass | database.password そのまま

// 実行環境が production の場合
c = &Config{}
toml.Load(c, "config.toml", "production")
fmt.Println(c.Database.Username) //=> user            | database.username そのまま
fmt.Println(c.Database.Password) //=> toolongpassword | database.production.password に上書きされている

おわりに

  • TOML いい感じなのでドッグフーディングもかねて使っていきたい
9
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
12