golang解析yaml配置文件踩坑

1.go在写struct的时候遇到重名的yaml配置,在struct中指定名称

type Discovery struct{
   Locator Locator `yaml:"locator,omitempty"`
}

type Locator struct {
   Enabled bool `yaml:"enabled,omitempty"`
}

type Gateway struct{
   Routes []Routes `yaml:"routes,omitempty"`
   Discovery Discovery `yaml:"discovery,omitempty"`
   DefaultFilters DefaultFilters `yaml:"default-filters,omitempty"`
}

type DefaultFilters struct{
   Name []string `yaml:"name,omitempty"`
   Args Args `yaml:"args,omitempty"`
}

type Predicates struct{
   Path string `yaml:"Path,flow,omitempty"`
}

type Filters struct{
   StripPrefix int `yaml:"StripPrefix,omitempty"`
   Name string `yaml:"name,omitempty"`
   Args Args `yaml:"args,omitempty"`
}

type Args struct{
   KeyResolver string `yaml:"key-resolver,omitempty"`
   RedisRateLimiterReplenishRate int `yaml:"redis-rate-limiter.replenishRate,omitempty"`
   RedisRateLimiterBurstCapacity int `yaml:"redis-rate-limiter.burstCapacity,omitempty"`
   Name string `yaml:"name,omitempty"`
   FallbackUri string `yaml:"fallbackUri,omitempty"`
}

type Routes struct{
   Id string `yaml:"id,omitempty"`
   Uri string `yaml:"uri,omitempty"`
   Predicates []Predicates `yaml:"predicates,omitempty"`
   Filters []Filters `yaml:"filters,omitempty"`
}

2.在回写yaml数据时会发现,当源文件中数据解析为struct后,重新写入文件数据会多出许多原来没有的内容,这时候在struct中加入omitempty参数就可以忽略空参数(0,"",nil),这样在会写数据时就不会多出不要的参数

3.在写struct的时候对于列表需要特别注意,写列表的时候要定义上一级为列表,否则会出现无法转化的情况出现,例如

type Routes struct{
   Id string `yaml:"id,omitempty"`
   Uri string `yaml:"uri,omitempty"`
   Predicates []Predicates `yaml:"predicates,omitempty"`
   Filters []Filters `yaml:"filters,omitempty"`
}
type Predicates struct{
   Path string `yaml:"Path,flow,omitempty"`
}

中的Predicates,如果将Path定义为列表而将Predicates定义为单个的struct

type Routes struct{
   Id string `yaml:"id,omitempty"`
   Uri string `yaml:"uri,omitempty"`
   Predicates Predicates `yaml:"predicates,omitempty"`
   Filters []Filters `yaml:"filters,omitempty"`
}
type Predicates struct{
   Path []string `yaml:"Path,flow,omitempty"`
}

那么在解析yaml文件时会出现无法转化对象的情况出现

line 15: cannot unmarshal !!seq into main.Predicates
line 17: cannot unmarshal !!seq into main.Filters

4.貌似有层级关系的key实际上没有层级关系

那么按照看起来的定义struct

type Args struct{
   KeyResolver string `yaml:"key-resolver,omitempty"`
   RedisRateLimiter RedisRateLimiter `yaml:"redis-rate-limiter,omitempty"`
   Name string `yaml:"name,omitempty"`
   FallbackUri string `yaml:"fallbackUri,omitempty"`
}

type RedisRateLimiter struct {
   ReplenishRate int `yaml:"replenishRate,omitempty"`
   BurstCapacity int `yaml:"burstCapacity,omitempty"`
}

然而实际解析数据时

所以还是按照它原本的key来定义才能正确解析到值

type Args struct{
   KeyResolver string `yaml:"key-resolver,omitempty"`
   RedisRateLimiterReplenishRate int `yaml:"redis-rate-limiter.replenishRate,omitempty"`
   RedisRateLimiterBurstCapacity int `yaml:"redis-rate-limiter.burstCapacity,omitempty"`
   Name string `yaml:"name,omitempty"`
   FallbackUri string `yaml:"fallbackUri,omitempty"`
}

5.解析不确定名称的子项,用map来指定

type Zuul struct{
   SensitiveHeaders string `yaml:"sensitive-headers,omitempty"`
   IgnoredHeaders string `yaml:"ignored-headers,omitempty"`
   Ribbon Ribbon `yaml:"ribbon,omitempty"`
   Routes map[string]ZullItem `yaml:"routes,omitempty"`
}
type ZullItem struct{
	Path string `yaml:"path,omitempty"`
}
zuul:
  sensitive-headers: Access-Control-Allow-Origin
  ignored-headers: Access-Control-Allow-Origin,H-APP-Id,APPToken
  ribbon:
    eager-load:
      enabled: true
  routes:
    Product:
      path: /product/**
    AuthorizationServer8002:
      path: /oauth/**
    Advantages:
      path: /advantages/**
    LeavingAMessage:
      path: /message/**
    Model:
      path: /model/**
    News:
      path: /news/**
**
    Advantages:
      path: /advantages/**
    LeavingAMessage:
      path: /message/**
    Model:
      path: /model/**
    News:
      path: /news/**