reading bool value using viper in Go

huangapple go评论131阅读模式
英文:

reading bool value using viper in Go

问题

我正在使用viper来管理Go应用程序的配置和环境变量。除了布尔值之外,所有的值都从JSON配置文件中正确获取,即使在JSON文件中有一个true值,布尔值始终为false。

{
  "database" : {
    "host" : "localhost",
    "port": "3306"
  },
  "host": "localhost",
  "port": ":3000",
  "production": true,
  "cache": true
}

配置包如下:

package config

import (
	"github.com/spf13/viper"
	"html/template"
	"log"
)

type ViperConfig struct {
	Database struct {
		Host string `json:'host'`
		Port string `json:'port'`
	} `json:'database'`
	Host          string `json:'host'`
	Port          string `json:'port'`
	ProductionMod bool   `json:'production'`
	UseCache      bool   `json:'cache'`
	TemplaCache   map[string]*template.Template
}

func LoadConfig(path string) (viperconfig ViperConfig, err error) {
	viper.AddConfigPath(path)
	viper.SetConfigName("config")
	viper.SetConfigType("json")
	viper.AutomaticEnv()
	err = viper.ReadInConfig()
	if err != nil {
		log.Fatal("无法加载配置文件")
	}
	err = viper.Unmarshal(&viperconfig)
	return
}

当我尝试访问任何字符串时,所有这些都能正常工作,但是当我尝试访问布尔变量时,它总是返回false。

package main

import (
	"github.com/alexedwards/scs/v2"
	"github.com/fouad82/news-api/cmd/config"
	"github.com/fouad82/news-api/cmd/routes"
	"log"
	"net/http"
	"time"
)

func main() {
	ViperConfig, err := config.LoadConfig("../")
	if err != nil {
		log.Fatal("无法读取viper配置", err)
	}
	if err != nil {
		log.Fatal("解析模板时出错", err)
	}
	session := scs.New()
	session.Lifetime = 24 * time.Hour
	session.Cookie.Persist = true
	session.Cookie.SameSite = http.SameSiteLaxMode
	session.Cookie.Secure = ViperConfig.ProductionMod
	routes.Routes()
	// 这些值始终为false,而不是实际值
	log.Fatal(ViperConfig.UseCache, ViperConfig.ProductionMod)
	http.ListenAndServe(ViperConfig.Port, nil)
}
英文:

I'm using viper to manage the configurations and environment variables for a Go app .<br>
all of values are coming correct from the json config file expect the bool values are always coming false even it have a true value within the json file

{
  &quot;database&quot; : {
    &quot;host&quot; : &quot;localhost&quot;,
    &quot;port&quot;: &quot;3306&quot;
  },
  &quot;host&quot;: &quot;localhost&quot;,
  &quot;port&quot;: &quot;:3000&quot;,
  &quot;production&quot;: true,
  &quot;cache&quot;: true
}

the configuration package

package config

import (
	&quot;github.com/spf13/viper&quot;
	&quot;html/template&quot;
	&quot;log&quot;
)

type ViperConfig struct {
	Database struct {
		Host string &quot;json:&#39;host&#39;&quot;
		Port string &quot;json:&#39;port&#39;&quot;
	} &quot;json:&#39;database&#39;&quot;
	Host          string &quot;json:&#39;host&#39;&quot;
	Port          string &quot;json:&#39;port&#39;&quot;
	ProductionMod bool   &quot;json:&#39;production&#39;&quot;
	UseCache      bool   &quot;json:&#39;cache&#39;&quot;
	TemplaCache   map[string]*template.Template
}

func LoadConfig(path string) (viperconfig ViperConfig, err error) {
	viper.AddConfigPath(path)
	viper.SetConfigName(&quot;config&quot;)
	viper.SetConfigType(&quot;json&quot;)
	viper.AutomaticEnv()
	err = viper.ReadInConfig()
	if err != nil {
		log.Fatal(&quot;Can&#39;t load config file&quot;)
	}
	err = viper.Unmarshal(&amp;viperconfig)
	return
}

all of this are working file when i tried to access any string but when tried to access the bool variables it always give false

package main

import (
	&quot;github.com/alexedwards/scs/v2&quot;
	&quot;github.com/fouad82/news-api/cmd/config&quot;
	&quot;github.com/fouad82/news-api/cmd/routes&quot;
	&quot;log&quot;
	&quot;net/http&quot;
	&quot;time&quot;
)

func main() {
	ViperConfig, err := config.LoadConfig(&quot;../&quot;)
	if err != nil {
		log.Fatal(&quot;Can&#39;t read viper configurations&quot;, err)
	}
	if err != nil {
		log.Fatal(&quot;Error Parsing template&quot;, err)
	}
	session := scs.New()
	session.Lifetime = 24 * time.Hour
	session.Cookie.Persist = true
	session.Cookie.SameSite = http.SameSiteLaxMode
	session.Cookie.Secure = ViperConfig.ProductionMod
	routes.Routes()
    // the values never gives the actuall value it always gives false
	log.Fatal(ViperConfig.UseCache, ViperConfig.ProductionMod)
	http.ListenAndServe(ViperConfig.Port, nil)
}

答案1

得分: 2

首先,json标签的写法是错误的。

我认为viper不使用json标签,而是使用mapstructure标签。
其他变量能够正常工作是因为变量的名称与映射到json标签上的名称相同。(请查看https://github.com/spf13/viper#unmarshaling)

有两种解决方案:

第一种:更改变量名称

type ViperConfig struct {
    Database struct {
        Host string `json:"host"`
        Port string `json:"port"`
    } `json:"database"`
    Host          string `json:"host"`
    Port          string `json:"port"`
    Production bool   `json:"production"`
    Cache      bool   `json:"cache"`
    TemplaCache   map[string]*template.Template
}

或者使用mapstructure标签

type ViperConfig struct {
    Database struct {
        Host string `json:"host"`
        Port string `json:"port"`
    } `json:"database"`
    Host          string `json:"host"`
    Port          string `json:"port"`
    ProductionMod bool   `json:"production" mapstructure:"production"`
    UseCache      bool   `json:"cache" mapstructure:"cache"`
    TemplaCache   map[string]*template.Template
}
英文:

First the json tags are written wrong.

I think viper doesn't use json tags. It uses the mapstructure tags.
The other variables are working because the name of the variable is the same mapped on the json tags. (check this https://github.com/spf13/viper#unmarshaling)

2 solutions:

First: change the variables name


type ViperConfig struct {
    Database struct {
        Host string `json:&quot;host&quot;`
        Port string `json:&quot;port&quot;`
    } `json:&quot;database&quot;`
    Host          string `json:&quot;host&quot;`
    Port          string `json:&quot;port&quot;`
    Production bool   `json:&quot;production&quot;`
    Cache      bool   `json:&quot;cache&quot;`
    TemplaCache   map[string]*template.Template
}

Or use mapstructure tags



type ViperConfig struct {
    Database struct {
        Host string `json:&quot;host&quot;`
        Port string `json:&quot;port&quot;`
    } `json:&quot;database&quot;`
    Host          string `json:&quot;host&quot;`
    Port          string `json:&quot;port&quot;`
    ProductionMod bool   `json:&quot;production&quot; mapstructure:&quot;production&quot;`
    UseCache      bool   `json:&quot;cache&quot; mapstructure:&quot;cache&quot;`
    TemplaCache   map[string]*template.Template
}

huangapple
  • 本文由 发表于 2021年7月16日 02:29:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/68399098.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定