This commit is contained in:
Tiger Wang 2022-07-07 17:57:11 -04:00
parent e2a41e5734
commit 80525a9837
8 changed files with 35 additions and 9 deletions

View File

@ -13,6 +13,15 @@ type ServerAppListCollection struct {
Version string `json:"version"` Version string `json:"version"`
} }
// @tiger - 对于用于出参的数据结构,静态信息(例如 title
// 动态信息(例如 state、query_count应该划分到不同的数据结构中
//
// 这样的好处是
// 1 - 多次获取动态信息时可以减少出参复杂度,因为静态信息只获取一次就好
// 2 - 在未来的迭代中,可以降低维护成本(所有字段都展开放在一个层级维护成本略高)
//
// 另外,一些针对性字段,例如 Docker 相关的,可以用 map 来保存。
// 这样在未来增加多态 App例如 Snap不需要维护多个结构或者一个结构保存不必要的字段
type ServerAppList struct { type ServerAppList struct {
Id uint `gorm:"column:id;primary_key" json:"id"` Id uint `gorm:"column:id;primary_key" json:"id"`
Title string `json:"title"` Title string `json:"title"`

View File

@ -18,7 +18,7 @@ type CategoryList struct {
//CreatedAt time.Time `json:"created_at"` //CreatedAt time.Time `json:"created_at"`
// //
//UpdatedAt time.Time `json:"updated_at"` //UpdatedAt time.Time `json:"updated_at"`
Font string `json:"font"` Font string `json:"font"` // @tiger - 如果这个和前端有关,应该不属于后端的出参范围,而是前端去界定
Name string `json:"name"` Name string `json:"name"`
Count uint `json:"count"` Count uint `json:"count"` // @tiger - count 属于动态信息,应该单独放在一个出参结构中(原因见另外一个关于 静态/动态 出参的注释)
} }

View File

@ -14,5 +14,5 @@ type DockerStatsModel struct {
Icon string `json:"icon"` Icon string `json:"icon"`
Title string `json:"title"` Title string `json:"title"`
Data interface{} `json:"data"` Data interface{} `json:"data"`
Pre interface{} `json:"pre"` Pre interface{} `json:"pre"` // @tiger - pre 不知道什么意思,可以提高一下描述性
} }

View File

@ -114,21 +114,34 @@ func InitRouter() *gin.Engine {
v1AppGroup := v1Group.Group("/app") v1AppGroup := v1Group.Group("/app")
v1AppGroup.Use() v1AppGroup.Use()
{ {
// @tiger - 按照 RESTFul 规范,改成 GET /v1/apps?installed=true
//获取我的已安装的列表 //获取我的已安装的列表
v1AppGroup.GET("/my/list", v1.MyAppList) v1AppGroup.GET("/my/list", v1.MyAppList)
//
// @tiger - 按照 RESTFul 规范,改成 GET /v1/apps/usage
v1AppGroup.GET("/usage", v1.AppUsageList) v1AppGroup.GET("/usage", v1.AppUsageList)
// @tiger - 按照 RESTFul 规范,改成 GET /v1/app/:id
//app详情 //app详情
v1AppGroup.GET("/appinfo/:id", v1.AppInfo) v1AppGroup.GET("/appinfo/:id", v1.AppInfo)
// @tiger - 按照 RESTFul 规范,改成 GET /v1/apps?installed=false
//获取未安装的列表 //获取未安装的列表
v1AppGroup.GET("/list", v1.AppList) v1AppGroup.GET("/list", v1.AppList)
// @tiger - 这个信息和应用无关,应该挪到 /v1/sys/port/avaiable
//获取端口 //获取端口
v1AppGroup.GET("/port", v1.GetPort) v1AppGroup.GET("/port", v1.GetPort)
// @tiger - RESTFul 路径中尽量不要有动词,同时这个信息和应用无关,应该挪到 /v1/sys/port/:port
//检查端口 //检查端口
v1AppGroup.GET("/check/:port", v1.PortCheck) v1AppGroup.GET("/check/:port", v1.PortCheck)
// @tiger - 应用分类和应用不是一类资源,应该挪到 GET /v1/app_categories
v1AppGroup.GET("/category", v1.CategoryList) v1AppGroup.GET("/category", v1.CategoryList)
// @tiger - Docker Terminal 和应用不是一类资源,应该挪到 GET /v1/container/:id/terminal
// 另外这个返回的不是一个 HTTP 响应,应该返回一个 wss:// 协议的 URL给前端由前端另行处理
v1AppGroup.GET("/terminal/:id", v1.DockerTerminal) v1AppGroup.GET("/terminal/:id", v1.DockerTerminal)
//app容器详情 //app容器详情
v1AppGroup.GET("/info/:id", v1.ContainerInfo) v1AppGroup.GET("/info/:id", v1.ContainerInfo)

View File

@ -83,6 +83,7 @@ func GetPort(c *gin.Context) {
p, _ = port2.GetAvailablePort(t) p, _ = port2.GetAvailablePort(t)
ok = !port2.IsPortAvailable(p, t) ok = !port2.IsPortAvailable(p, t)
} }
// @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p}) c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: p})
} }
@ -117,8 +118,8 @@ func MyAppList(c *gin.Context) {
position, _ := strconv.ParseBool(c.DefaultQuery("position", "true")) position, _ := strconv.ParseBool(c.DefaultQuery("position", "true"))
list, unTranslation := service.MyService.App().GetMyList(index, size, position) list, unTranslation := service.MyService.App().GetMyList(index, size, position)
data := make(map[string]interface{}, 2) data := make(map[string]interface{}, 2)
data["list"] = list data["list"] = list // @tiger - list 不清楚是什么意思,可以提高一下描述性
data["local"] = unTranslation data["local"] = unTranslation // @tiger - local 不清楚是什么意思,可以提高一下描述性
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
} }
@ -131,6 +132,7 @@ func MyAppList(c *gin.Context) {
// @Success 200 {string} string "ok" // @Success 200 {string} string "ok"
// @Router /app/usage [get] // @Router /app/usage [get]
func AppUsageList(c *gin.Context) { func AppUsageList(c *gin.Context) {
// @tiger - 关于出参的问题,见 GetHardwareUsageSteam - 另外 steam 是不是应该为 stream?
list := service.MyService.App().GetHardwareUsage() list := service.MyService.App().GetHardwareUsage()
c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list})
} }

View File

@ -470,7 +470,7 @@ func GetSystemSocketPort(c *gin.Context) {
model.Result{ model.Result{
Success: common_err.SUCCESS, Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS), Message: common_err.GetMsg(common_err.SUCCESS),
Data: config.ServerInfo.SocketPort, // @tiger 这里最好封装成 {'port': ...} 的形式,来增加出参的上下文 Data: config.ServerInfo.SocketPort, // @tiger 这里最好封装成 {'port': ...} 的形式,来体现出参的上下文
}) })
} }

View File

@ -438,6 +438,8 @@ func (a *appStruct) GetHardwareUsageSteam() {
dockerStats.Icon = v.Labels["icon"] dockerStats.Icon = v.Labels["icon"]
dockerStats.Title = strings.ReplaceAll(v.Names[0], "/", "") dockerStats.Title = strings.ReplaceAll(v.Names[0], "/", "")
// @tiger - 不建议直接把依赖的数据结构封装返回。
// 如果依赖的数据结构有变化,应该在这里适配或者保存,这样更加对客户端负责
temp.Store(v.ID, dockerStats) temp.Store(v.ID, dockerStats)
if i == 99 { if i == 99 {
stats.Body.Close() stats.Body.Close()

View File

@ -67,13 +67,13 @@ type MyAppList struct {
Index string `json:"index"` Index string `json:"index"`
//Order string `json:"order"` //Order string `json:"order"`
Port string `json:"port"` Port string `json:"port"`
UpTime string `json:"up_time"` UpTime string `json:"up_time"` // @tiger - 如果是安装时间,应该写 installed_at。
Slogan string `json:"slogan"` Slogan string `json:"slogan"`
Type string `json:"type"` Type string `json:"type"`
//Rely model.MapStrings `json:"rely"` //[{"mysql":"id"},{"mysql":"id"}] //Rely model.MapStrings `json:"rely"` //[{"mysql":"id"},{"mysql":"id"}]
Image string `json:"image"` Image string `json:"image"`
Volumes string `json:"volumes"` Volumes string `json:"volumes"`
NewVersion bool `json:"new_version"` NewVersion bool `json:"new_version"` // @tiger - 无法从词面理解含义,感觉可以更加有描述性
Host string `json:"host"` Host string `json:"host"`
Protocol string `json:"protocol"` Protocol string `json:"protocol"`
} }