feat(lyra): 搭建基础骨架与配置响应组件

- 使用 Viper 加载 TOML 配置
- 定义统一响应、业务错误码及响应辅助函数
- 添加分层职责约束并同步架构文档
This commit is contained in:
2026-10-16 23:36:34 +08:00
parent e4fc4af912
commit 8b320817ed
19 changed files with 418 additions and 22 deletions
+5
View File
@@ -0,0 +1,5 @@
# api 包
- 定义 HTTP 请求/响应 DTO,按资源分文件。
- DTO 与内部模型分开:即使初期字段相近,也不把数据库模型直接暴露为响应,由 handler 层完成显式转换。
- 不引用 handler、service、model,也不依赖 Gin,避免传输契约与实现耦合或循环引用。
+21
View File
@@ -0,0 +1,21 @@
package api
// ErrCode 错误码,前3位数表示错误类型,后3位数表示具体错误
type ErrorCode int
const (
CodeInvalidArgument ErrorCode = 10001
CodeInternalError ErrorCode = 10002
CodeLinkNotFound ErrorCode = 10003
)
func (e ErrorCode) Message() string {
switch e {
case CodeInvalidArgument:
return "请求参数不正确"
case CodeLinkNotFound:
return "链接不存在"
default:
return "服务暂时不可用"
}
}
+13
View File
@@ -0,0 +1,13 @@
package api
type Response struct {
Success bool `json:"success"`
Data any `json:"data,omitempty"`
Error *ErrorInfo `json:"error,omitempty"`
}
type ErrorInfo struct {
Code ErrorCode `json:"code"`
Message string `json:"message"`
Debug string `json:"debug,omitempty"`
}
@@ -0,0 +1,4 @@
# config 包
- 负责配置定义与加载。
- 具体配置项、来源与加载方式随实际需求确定,由程序入口调用配置加载逻辑。
@@ -0,0 +1,39 @@
package config
import (
"fmt"
"github.com/spf13/viper"
)
type Config struct {
App AppConfig `mapstructure:"app"`
HTTP HTTPConfig `mapstructure:"http"`
}
type AppConfig struct {
Name string `mapstructure:"name"`
Env string `mapstructure:"env"`
}
type HTTPConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
}
func Load(path string) (*Config, error) {
v := viper.New()
// 指定文件,按 .toml 扩展名识别格式
v.SetConfigFile(path)
if err := v.ReadInConfig(); err != nil {
return nil, fmt.Errorf("读取配置失败: %w", err)
}
var cfg Config
if err := v.Unmarshal(&cfg); err != nil {
return nil, fmt.Errorf("解析配置失败: %w", err)
}
return &cfg, nil
}
@@ -0,0 +1,5 @@
# handler 包
- 负责参数绑定、API DTO 与内部模型的相互转换、响应输出。
- 引用 internal/api 的 DTO,使用 Gin 完成绑定与响应。
- 调用 service 时传递标准 context.Context,不下传 gin.Context。
@@ -0,0 +1,4 @@
# httpx 包
- 提供公共 HTTP 响应辅助。
- 出现实际复用需求时再补充具体辅助函数,不预先设计无使用场景的抽象。
@@ -0,0 +1,27 @@
package httpx
import (
"lyra/internal/api"
"net/http"
"github.com/gin-gonic/gin"
)
// OK 成功响应
func OK(c *gin.Context, data any) {
c.JSON(http.StatusOK, api.Response{
Success: true,
Data: data,
})
}
// Fail 错误响应
func Fail(c *gin.Context, status int, code api.ErrorCode, message string) {
if message == "" {
message = code.Message()
}
c.JSON(status, api.Response{
Success: false,
Error: &api.ErrorInfo{Code: code, Message: message},
})
}
@@ -0,0 +1,6 @@
# model 包
- 承载数据结构定义与数据访问:使用 Squirrel/SQL 构造查询、sqlx 执行与映射结果,驱动为 pgx stdlib。
- SQL 与查询逻辑显式写在这一层,不使用 ORM 自动持久化。
- 支持在 service 传入的同一事务内执行操作。
- 使用标准 context.Context,不依赖 Gin,也不依赖 internal/api 的 DTO。
@@ -0,0 +1,4 @@
# postgres 包
- 负责建立与管理 PostgreSQL 连接,使用 pgx stdlib 驱动。
- 连接参数来自 internal/config,连接供 model 层通过 sqlx 执行查询使用。
@@ -0,0 +1,5 @@
# router 包
- 负责路由注册与项目路径前缀,例如 `/api/polaris`。
- Gin 的路由与请求处理逻辑留在 HTTP 层;service 和 model 不依赖 Gin。
- 路由随资源实现逐步补充,不按业务项目建立代码子目录。
@@ -0,0 +1,5 @@
# service 包
- 承载业务规则与事务协调,通过 model 完成数据访问。
- 需要原子性时,在同一事务内协调多次写入,不把各自独立提交的多次写入当成原子业务。
- 使用标准 context.Context,不依赖 Gin,也不依赖 internal/api 的 DTO。