Add HTTP /v1 MVC, TCP send path, groups with server-side member-avatar collage, object-storage upload, and friends/favorites around the architecture-v3 layout. Co-authored-by: Cursor <cursoragent@cursor.com>
147 lines
3.6 KiB
Go
147 lines
3.6 KiB
Go
package httpx
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"spark-server/internal/pkg/errs"
|
|
"spark-server/internal/pkg/i18n"
|
|
"spark-server/internal/pkg/reply"
|
|
"spark-server/internal/pkg/reqctx"
|
|
authhandler "spark-server/internal/transport/http/handler/auth"
|
|
favhandler "spark-server/internal/transport/http/handler/favorite"
|
|
filehandler "spark-server/internal/transport/http/handler/file"
|
|
friendhandler "spark-server/internal/transport/http/handler/friend"
|
|
grouphandler "spark-server/internal/transport/http/handler/group"
|
|
userhandler "spark-server/internal/transport/http/handler/user"
|
|
"spark-server/internal/transport/http/respond"
|
|
)
|
|
|
|
func registerRoutes(r *gin.Engine, deps *EngineDeps) {
|
|
registerDocs(r)
|
|
registerHealth(r, deps.Health)
|
|
v1 := r.Group("/v1")
|
|
registerAuthRoutes(v1, deps)
|
|
registerUserRoutes(v1, deps)
|
|
registerFriendRoutes(v1, deps)
|
|
registerGroupRoutes(v1, deps)
|
|
registerFileRoutes(v1, deps)
|
|
registerFavoriteRoutes(v1, deps)
|
|
}
|
|
|
|
func registerHealth(r *gin.Engine, h Health) {
|
|
r.GET("/healthz", func(c *gin.Context) {
|
|
JSON(c, gin.H{"status": "ok"})
|
|
})
|
|
r.GET("/readyz", func(c *gin.Context) {
|
|
if h == nil {
|
|
JSON(c, gin.H{"status": "ok", "ready": true})
|
|
return
|
|
}
|
|
ok, data := h.Ready(c.Request.Context())
|
|
if ok {
|
|
JSON(c, data)
|
|
return
|
|
}
|
|
lang := reqctx.Lang(c.Request.Context())
|
|
c.JSON(http.StatusServiceUnavailable, reply.FailData(
|
|
errs.ErrAvailable.Code,
|
|
i18n.ErrorMsg(lang, errs.ErrAvailable.Code),
|
|
data,
|
|
))
|
|
})
|
|
}
|
|
|
|
func registerAuthRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
g := v1.Group("/auth")
|
|
if deps.Login == nil {
|
|
return
|
|
}
|
|
h := authhandler.New(deps.Login)
|
|
g.POST("/login", h.Login)
|
|
g.POST("/email-codes", h.SendEmailCode)
|
|
g.POST("/token/refresh", h.Refresh)
|
|
g.POST("/logout", h.Logout)
|
|
}
|
|
|
|
func registerUserRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Users == nil {
|
|
return
|
|
}
|
|
h := userhandler.New(deps.Users)
|
|
g := v1.Group("/users")
|
|
g.GET("/me", h.Me)
|
|
g.PATCH("/me", h.PatchMe)
|
|
}
|
|
|
|
func registerFriendRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Friends == nil {
|
|
return
|
|
}
|
|
h := friendhandler.New(deps.Friends)
|
|
g := v1.Group("/friends")
|
|
g.GET("/lookup", h.Lookup)
|
|
g.GET("/requests", h.ListRequests)
|
|
g.POST("/requests", h.Apply)
|
|
g.GET("", h.List)
|
|
g.POST("", h.Accept)
|
|
g.GET("/:uid", h.Get)
|
|
g.DELETE("/:uid", h.Delete)
|
|
g.PUT("/:uid/remark", h.Remark)
|
|
g.PUT("/:uid/block", h.Block)
|
|
g.DELETE("/:uid/block", h.Unblock)
|
|
g.POST("/:uid/reports", h.Report)
|
|
}
|
|
|
|
func registerGroupRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Groups == nil {
|
|
return
|
|
}
|
|
h := grouphandler.New(deps.Groups)
|
|
g := v1.Group("/groups")
|
|
g.POST("", h.Create)
|
|
g.GET("", h.List)
|
|
g.GET("/:id/members", h.ListMembers)
|
|
g.POST("/:id/members", h.Invite)
|
|
g.PATCH("/:id/members/:uid", h.UpdateMember)
|
|
g.DELETE("/:id/members/:uid", h.RemoveMember)
|
|
g.POST("/:id/transfer", h.Transfer)
|
|
g.GET("/:id", h.Get)
|
|
g.PATCH("/:id", h.Update)
|
|
g.DELETE("/:id", h.Dissolve)
|
|
}
|
|
|
|
func registerFileRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Files == nil {
|
|
return
|
|
}
|
|
h := filehandler.New(deps.Files)
|
|
g := v1.Group("/files")
|
|
g.POST("", h.Create)
|
|
g.POST("/downloads", h.Download)
|
|
}
|
|
|
|
func registerFavoriteRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Favorites == nil {
|
|
return
|
|
}
|
|
h := favhandler.New(deps.Favorites)
|
|
g := v1.Group("/favorites")
|
|
g.GET("", h.List)
|
|
g.POST("", h.Create)
|
|
g.DELETE("/:id", h.Delete)
|
|
}
|
|
|
|
func JSON(c *gin.Context, data any) {
|
|
respond.JSON(c, data)
|
|
}
|
|
|
|
func JSONError(c *gin.Context, err error) {
|
|
respond.JSONError(c, err)
|
|
}
|
|
|
|
func BindJSON(c *gin.Context, dst any) error {
|
|
return respond.BindJSON(c, dst)
|
|
}
|