配置
介绍
Goyave 提供了一个灵活的结构化配置系统,支持文件配置同时也支持环境变量。框架的大部分核心都是可配置的。任何其他包也可以注册自己的配置条目。
要配置您的应用程序,请使用项目根目录下的 config.json 文件。如果配置文件缺少某些条目,将使用默认值。请参阅下面的配置参考以了解更多信息。
术语
条目:配置条目是使用键访问的值。键具有点分隔的格式。(例如:app.name)
注册条目:通知框架期望具有给定键的条目。注册条目允许设置默认值,如果应用程序配置文件中未提供此条目,则使用默认值,强制执行此条目的某种类型(例如,如果需要是整数),并设置允许的值列表。
类别:类别在配置文件中由 JSON 对象表示,由大括号界定。子类别是不是根级别的类别。例如:server.proxy 是 server 类别的子类别。
加载配置
自动加载
默认情况下,在使用 goyave.New() 初始化服务器时自动加载配置。
大多数项目需要基于环境的不同配置值。例如,如果您在本地开发、在持续集成管道内的测试环境中或在生产环境中,您不会连接到同一个数据库。Goyave 支持多种配置。如果您使用 config.Load() 或自动加载器,框架将根据环境变量 GOYAVE_ENV 选择适当的文件。
| GOYAVE_ENV | 配置文件 |
|---|---|
| test | config.test.json |
| production | config.production.json |
| custom_env | config.custom_env.json |
| local / localhost / 未设置 | config.json |
如果您想使用相同的逻辑自己加载配置,可以使用 config.Load():
import (
"fmt"
"os"
"goyave.dev/goyave/v5/config"
"goyave.dev/goyave/v5/util/errors"
)
func main() {
cfg, err := config.Load()
if err != nil {
fmt.Fprintln(os.Stderr, err.(*errors.Error).String())
os.Exit(1)
}
opts := goyave.Options{
Config: cfg,
}
//...
}从文件加载
您可以使用绝对路径或相对于工作目录的路径加载配置文件。
import (
"fmt"
"os"
"goyave.dev/goyave/v5/config"
"goyave.dev/goyave/v5/util/errors"
)
func main() {
cfg, err := config.LoadFrom("config.json")
if err != nil {
fmt.Fprintln(os.Stderr, err.(*errors.Error).String())
os.Exit(1)
}
opts := goyave.Options{
Config: cfg,
}
//...
}从 JSON 或嵌入加载
您还可以选择从原始 JSON 字符串或 embed 加载配置。
import (
_ "embed"
"fmt"
"os"
"goyave.dev/goyave/v5/config"
"goyave.dev/goyave/v5/util/errors"
)
//go:embed config.json
var cfgJSON string
func main() {
cfg, err := config.LoadJSON(cfgJSON)
if err != nil {
fmt.Fprintln(os.Stderr, err.(*errors.Error).String())
os.Exit(1)
}
opts := goyave.Options{
Config: cfg,
}
//...
}TIP
您可以使用构建约束为每个环境加载不同的配置文件。为每个环境创建一个 config_<env>.go 文件。
config_local.go
//go:build !production && !staging
package main
import _ "embed"
//go:embed config.json
var cfgJSON stringconfig_production.go
//go:build production
package main
import _ "embed"
//go:embed config.production.json
var cfgJSON string然后使用构建标签:go run -tags production 或 go build -tags production。
验证
所有条目都经过验证。这意味着如果您在配置中提供了无效值(例如,如果指定的端口不是数字),应用程序将不会启动。
每个条目都注册了默认值、类型和授权值。从 JSON 解析的原始值可能会转换为期望的类型(如果值允许)。例如,JSON 中解析的数字默认总是 float64,但如果条目指定类型为 int,配置加载器将尝试将数字转换为 int。如果条目被指定为切片,它将被转换为期望类型的切片,而不是总是以 []any 结束。
环境变量
您可以在配置文件中使用环境变量。环境变量通过以下语法识别:${VARIABLE_NAME}。
{
"database": {
"host": "${DB_HOST}"
}
}注意:此语法是严格的。如果字符串不以 ${ 开头或不以 } 结尾,则不会被视为环境变量。因此,不支持像 ${VAR_1}-${VAR_2} 这样的模板。
支持 string、int、float64 和 bool 值。如果配置条目期望是这些类型之一,环境变量的内容将自动转换,如上文验证部分所述。如果转换失败,将返回配置加载错误。
如果配置文件中提到的环境变量未设置,配置验证将不会通过。切片内部不支持环境变量。
使用配置
所有条目都可以使用点分隔路径访问。例如,如果您想访问 app 类别中的 name 条目,键将是 app.name。您不能一次检索整个类别。
cfg.Get("app.name") // 类型 any
cfg.GetString("app.name")
cfg.GetBool("app.debug")
cfg.GetInt("server.port")
cfg.GetFloat("server.maxUploadSize")
cfg.GetStringSlice("path.to.slice")
cfg.GetBoolSlice("path.to.slice")
cfg.GetIntSlice("path.to.slice")
cfg.GetFloatSlice("path.to.slice")
cfg.Has("custom_entry") // 如果条目存在则返回 true如果请求的条目不是 getter 期望的类型,函数将 panic。
请参阅参考。
配置参考
应用
| 条目 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| app.name | string | "goyave" | |
| app.environment | string | "localhost" | |
| app.debug | bool | true | 激活时,使用人类可读的日志格式化器而不是 JSON 结构化日志,并在响应中发送错误详情。在生产环境中禁用此功能! |
| app.defaultLanguage | string | "en-US" | 参见本地化部分 |
服务器
| 条目 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| server.host | string | "127.0.0.1" | |
| server.domain | string | "" | 用于 URL 生成。留空以使用 IP。 |
| server.port | int | 8080 | 如果设置为 0,则自动选择端口号,可以通过 server.Port() 检索。所选端口不反映在配置中。 |
| server.writeTimeout | int | 10 | *http.Server 的 WriteTimeout(秒) |
| server.readTimeout | int | 10 | *http.Server 的 ReadTimeout(秒) |
| server.readHeaderTimeout | int | 10 | *http.Server 的 ReadHeaderTimeout(秒) |
| server.idleTimeout | int | 20 | *http.Server 的 IdleTimeout(秒) |
| server.websocketCloseTimeout | int | 10 | WebSocket 关闭握手的最大时间(秒) |
| server.maxUploadSize | float64 | 10 | 请求的最大大小,单位 MiB |
代理
此部分用于 URL 生成(server.ProxyBaseURL()),如果您在反向代理(如 nginx 或 apache)后面运行应用程序。这些条目对网络没有影响,也不是必需的。
| 条目 | 类型 | 接受的值 | 默认值 | 说明 |
|---|---|---|---|---|
| server.proxy.protocol | string | "http", "https" | "http" | |
| server.proxy.host | string | 任意 | 代理的公共主机或域名 | |
| server.proxy.port | int | 任意 | 80 | |
| server.proxy.base | string | 任意 | "" | 基础路径(通常以 / 开头) |
数据库
| 条目 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| database.connection | string | "none" | 参见数据库指南 |
| database.host | string | "127.0.0.1" | |
| database.port | int | 0 | |
| database.name | string | "" | |
| database.username | string | "" | |
| database.password | string | "" | |
| database.options | string | "" | 创建连接时传递给 DSN 的选项。 |
| database.maxOpenConnections | int | 20 | |
| database.maxIdleConnections | int | 20 | |
| database.maxLifetime | int | 300 | 连接可重用的最长时间(秒)。 |
| database.defaultReadQueryTimeout | int | 20000 | 读取查询的最大执行时间(毫秒) |
| database.defaultWriteQueryTimeout | int | 40000 | 写入查询的最大执行时间(毫秒) |
Gorm 配置
| 条目 | 类型 | 默认值 |
|---|---|---|
| database.config.skipDefaultTransaction | bool | false |
| database.config.dryRun | bool | false |
| database.config.prepareStmt | bool | true |
| database.config.disableNestedTransaction | bool | false |
| database.config.allowGlobalUpdate | bool | false |
| database.config.disableAutomaticPing | bool | false |
| database.config.disableForeignKeyConstraintWhenMigrating | bool | false |
TIP
有关更多详细信息,请参阅 Gorm 的文档。
自定义配置条目
配置可以扩展。您开发的插件或包很可能使用某种形式的选项。这些选项可以添加到配置系统中,因此不需要在代码中设置或进行一些布线。
您可以使用 config.Register() 注册新的配置条目及其验证。
WARNING
未注册的配置条目仍然可以加载。但是,它们的类型将根据从配置文件解析的值自动确定。为了利用验证和转换系统,并确保您的自定义条目具有您期望的类型,您应始终使用 config.Register() 注册它们。
每个模块应在 init() 函数中注册其配置条目,即使它们没有默认值,以确保它们将被验证。 每个模块应使用自己的类别,并使用既表达性强又唯一的名称以避免冲突。 例如,auth 包注册了 auth.basic.username 和 auth.jwt.expiry 等,从而为其包创建一个类别,并为其功能创建两个子类别。
要注册没有默认值的条目(仅指定如何验证),将 Entry.Value 设置为 nil。您可以将 Entry.Required 设置为 true 以防止 nil 值。
如果此键的条目已存在且与作为此函数参数传递的条目不完全相同,则会 panic。另一方面,如果条目相同,则不会发生冲突,因此配置保持当前状态。
import (
"reflect"
"goyave.dev/goyave/v5/config"
)
func init() {
config.Register("customCategory.customEntry", config.Entry{
Value: "默认值",
Type: reflect.String,
IsSlice: false,
AuthorizedValues: []any{},
Required: true,
})
}