goではjsonを主な構成フォーマットとして使用します


最近goで再構築していますが、以前のコードではiniファイルを使用して構成していましたが、多くの歴史的な問題が残っているため、構成が混乱し、メンテナンスが困難になり、再構築も考慮する必要があります.
汎用構成フォーマット
共通のコンフィギュレーションフォーマットはたくさんありますが、ini、json、yaml、xmlなどがよく使われています.もちろん、共通のためにカスタムのコンフィギュレーションフォーマットは考えません.では、どのように選択しますか?
まず、xmlは考えなくてもいいです.今まではこれを使って配置するのが便利だとは思いませんでしたが、かえって太っていて、java系の子供靴が人気があるかもしれません.
さらにiniを考えると、iniファイルは簡単なアプリケーションの構成に非常に便利であり、構成に階層があまりない場合は、iniを使用すると私たちのニーズを完全に満たすことができ、あっても特定の接頭辞を加えることで解決することができます.たとえば、次のようなredis構成があります.
[ModuleA]

persistent_redis_addr = 127.0.0.1:6379
persistent_redis_password = admin

cache_redis_addr = 127.0.0.1:6380
cache_redis_password = admin

その後、需要が変化し、別の永続化redisサービスが必要になり、構成は次のようになります.
[ModuleA]

persistent_redis_addr = 127.0.0.1:6379
persistent_redis_password = admin

persistent2_redis_addr = 127.0.0.1:6379
persistent2_redis_password = admin

cache_redis_addr = 127.0.0.1:6380
cache_redis_password = admin

プレフィックスネーミングで階層的な問題は解決できますが、プログラマーにはあまり友好的ではないような気がします.
why json
残りはjsonとyamlで、この2つは比較的良い軽量レベルの構成フォーマットであり、プログラマーに非常に友好的であり、goの中でstructを定義することで、階層構造の構成を対応するstructにマッピングすることができる.
しかし、私はやはりjsonを私たちのgoコードのデフォルトの構成フォーマットとして選択することにしました.最も主要な原因はgoのjsonパッケージに殺し屋レベルのRawMessage実装があることです.これは私が見つけられるyamlパッケージにはありません.
RawMessageは主にgo遅延解析を教えるために用いられる.あるフィールドをRawMessageとして定義すると、goはこのjsonを解析しません.これにより、それぞれのサブモジュールにプッシュして個別に解析することができます.
バックグラウンドストレージはredisまたはmysqlのいずれかの機能があるとしますが、1つしか使用されません.次のように構成を書きます.
redis_store : {
    addr : 127.0.0.1
    db : 0
},

mysql_store : {
    addr : 127.0.0.1
    db : test
    password : admin
    user : root
}

store : redis

対応するclassは
type Config struct {
    RedisStore struct {
        Addr string
        DB int
    }

    MysqlStore Struct {
        Addr string
        DB string
        Password string
        User string
    }

    Store string
}

この時点で新しいstoreを追加する場合は、Configファイルに新しいfieldを追加する必要がありますが、実際には1つのstoreしか使用できません.こんなに多くの構成を書く必要はありません.
RawMessageを使用して処理できます.
type Config struct {
    Store string
    StoreConfig json.RawMessage
}

redisを使用する場合、対応するプロファイルは
store: redis
store_config: {
    addr : 127.0.0.1
    db : 0
}

mysqlを使用する場合、対応するプロファイルは
store: mysql
store_config: {
    addr : 127.0.0.1
    db : test
    password : admin
    user : root
}

goプロファイルを読み込んだ後は、RawMessageに対応するものではなく、私たちのコード自身に対応するstoreモジュールで処理します.これにより、プロファイルがどのように変更されても、storeモジュールがどのように変更されても、コンフィグクラスには影響しません.
各モジュールでは、関連するconfigを自分で定義するだけで、RawMessageを直接解析してそのconfigにマッピングすることができます.例えば、redisでは、モジュールには次のような定義があります.
type RedisConfig config {
    Addr string `json:"addr"`
    DB int `json:"db"`
}

func NewConfig(m json.RawMessage) *RedisConfig {
    c := new(RedisConfig)

    json.Unmarshal(m, c)

    return c
}

jsonの不足
jsonを使うのも卵が痛いところがたくさんありますが、最大の問題は注釈です.jsonでは、このように書くことはできません.
{
    //this is a comment
    /*this is a comment*/ 
}

しかし、構成項目が何をしているのかを説明するために注釈を書かないわけにはいきません.そのため、通常はコメントフィールドを導入する方法を採用しています.例えば、次のようにします.
{
    "_comment" : "this is a comment",
    "key" : "value"
}

また、jsonが注意しなければならないのは、書くときに最後の項目にカンマを付けてはいけないことです.このようなjsonはフォーマットの間違いで解析できません.
{
    "key" : "value",
}

最後にそのカンマは要らないが、実際に配置を書くときはいつも手当たり次第につけている.
しかし、総じて言えば、jsonはgoのプロジェクトに対してまだ友好的で、私はプロジェクトの中で推進しただけでなく、自分のオープンソースプロジェクトの中で、jsonを主なプロファイルとして大量に採用しました.