package httproutes import ( "net/http" "hyapp/services/gateway-service/internal/transport/http/httpkit" ) const APIV1Prefix = "/api/v1" type Wrapper func(http.HandlerFunc) http.Handler type Config struct { PublicWrap Wrapper AuthWrap Wrapper ProfileWrap Wrapper Auth AuthHandlers App AppHandlers User UserHandlers Manager ManagerHandlers Room RoomHandlers Message MessageHandlers Task TaskHandlers Wallet WalletHandlers VIP VIPHandlers Game GameHandlers } type AuthHandlers struct { LoginPassword http.HandlerFunc SetPassword http.HandlerFunc LoginThirdParty http.HandlerFunc RefreshToken http.HandlerFunc Logout http.HandlerFunc } type AppHandlers struct { ListRegistrationCountries http.HandlerFunc GetAppBootstrap http.HandlerFunc ListH5Links http.HandlerFunc ListAppBanners http.HandlerFunc ListResources http.HandlerFunc GetResourceGroup http.HandlerFunc ListGifts http.HandlerFunc IssueTencentIMUserSig http.HandlerFunc IssueTencentRTCToken http.HandlerFunc HandleTencentIMCallback http.HandlerFunc HandleTencentRTCCallback http.HandlerFunc UploadFile http.HandlerFunc UploadAvatar http.HandlerFunc HandlePushToken http.HandlerFunc } type UserHandlers struct { ResolveDisplayUserID http.HandlerFunc BatchUserProfiles http.HandlerFunc BatchRoomDisplayProfiles http.HandlerFunc GetMyOverview http.HandlerFunc GetMyIdentity http.HandlerFunc GetMyHostIdentity http.HandlerFunc GetMyRoleSummary http.HandlerFunc CompleteMyOnboarding http.HandlerFunc UpdateMyProfile http.HandlerFunc ChangeMyCountry http.HandlerFunc ChangeMyDisplayUserID http.HandlerFunc ApplyMyPrettyDisplayUserID http.HandlerFunc ListMyProfileVisitors http.HandlerFunc ListMyFollowing http.HandlerFunc ListMyFriends http.HandlerFunc ListMyFriendApplications http.HandlerFunc GetMyProfile http.HandlerFunc ListMyResources http.HandlerFunc EquipMyResource http.HandlerFunc UserSocialAction http.HandlerFunc } type ManagerHandlers struct { ListManagerGrantResources http.HandlerFunc GrantManagerResource http.HandlerFunc LookupBusinessUsers http.HandlerFunc } type RoomHandlers struct { GetMyRoom http.HandlerFunc ListRoomFeeds http.HandlerFunc ListRooms http.HandlerFunc GetCurrentRoom http.HandlerFunc GetRoomSnapshot http.HandlerFunc GetRoomDetail http.HandlerFunc ListRoomOnlineUsers http.HandlerFunc GetRoomGiftPanel http.HandlerFunc CreateRoom http.HandlerFunc UpdateRoomProfile http.HandlerFunc JoinRoom http.HandlerFunc RoomHeartbeat http.HandlerFunc LeaveRoom http.HandlerFunc CloseRoom http.HandlerFunc MicUp http.HandlerFunc MicDown http.HandlerFunc ChangeMicSeat http.HandlerFunc ConfirmMicPublishing http.HandlerFunc SetMicMute http.HandlerFunc SetMicSeatLock http.HandlerFunc SetChatEnabled http.HandlerFunc SetRoomAdmin http.HandlerFunc TransferRoomHost http.HandlerFunc MuteUser http.HandlerFunc KickUser http.HandlerFunc UnbanUser http.HandlerFunc SendGift http.HandlerFunc } type MessageHandlers struct { ListMessageTabs http.HandlerFunc MarkInboxSectionRead http.HandlerFunc MarkInboxMessageReadPath http.HandlerFunc DeleteInboxMessagePath http.HandlerFunc ListInboxMessages http.HandlerFunc } type TaskHandlers struct { ListTaskTabs http.HandlerFunc ClaimTaskReward http.HandlerFunc } type WalletHandlers struct { GetWalletOverview http.HandlerFunc GetMyBalances http.HandlerFunc ListRechargeProducts http.HandlerFunc GetDiamondExchangeConfig http.HandlerFunc ApplyWithdrawal http.HandlerFunc ListWalletTransactions http.HandlerFunc TransferCoinFromSeller http.HandlerFunc } type VIPHandlers struct { GetMyVIP http.HandlerFunc ListVIPPackages http.HandlerFunc PurchaseVIP http.HandlerFunc } type GameHandlers struct { ListGames http.HandlerFunc LaunchGame http.HandlerFunc HandleCallback http.HandlerFunc } type routes struct { mux *http.ServeMux config Config } // New 只维护 gateway 对外 HTTP 路径到 transport handler 的绑定。 // 业务状态和命令执行仍然全部下沉到 owner service,路由层不承载业务规则。 func New(config Config) http.Handler { mux := http.NewServeMux() routes := routes{mux: mux, config: config} routes.registerAuthRoutes() routes.registerAppRoutes() routes.registerUserRoutes() routes.registerManagerRoutes() routes.registerRoomRoutes() routes.registerMessageRoutes() routes.registerTaskRoutes() routes.registerWalletRoutes() routes.registerVIPRoutes() routes.registerGameRoutes() return mux } func (r routes) public(path string, method string, next http.HandlerFunc) { r.register(path, method, r.config.PublicWrap, next) } func (r routes) auth(path string, method string, next http.HandlerFunc) { r.register(path, method, r.config.AuthWrap, next) } func (r routes) profile(path string, method string, next http.HandlerFunc) { r.register(path, method, r.config.ProfileWrap, next) } func (r routes) register(path string, method string, wrap Wrapper, next http.HandlerFunc) { if method != "" { // method 继续走 gateway envelope,而不是使用 ServeMux 自动 405。 next = httpkit.RequireMethod(method, next) } r.mux.Handle(APIV1Prefix+path, wrap(next)) } func (r routes) registerAuthRoutes() { h := r.config.Auth r.public("/auth/account/login", "", h.LoginPassword) r.auth("/auth/password/set", "", h.SetPassword) r.public("/auth/third-party/login", "", h.LoginThirdParty) r.public("/auth/token/refresh", "", h.RefreshToken) r.public("/auth/logout", "", h.Logout) } func (r routes) registerAppRoutes() { h := r.config.App r.public("/countries", "", h.ListRegistrationCountries) r.public("/app/bootstrap", "", h.GetAppBootstrap) r.public("/app/h5-links", "", h.ListH5Links) r.public("/app/banners", "", h.ListAppBanners) r.public("/resources", "", h.ListResources) r.public("/resource-groups/{group_id}", "", h.GetResourceGroup) r.public("/gifts", "", h.ListGifts) r.profile("/im/usersig", http.MethodGet, h.IssueTencentIMUserSig) r.profile("/rtc/token", http.MethodPost, h.IssueTencentRTCToken) r.public("/tencent-im/callback", "", h.HandleTencentIMCallback) r.public("/tencent-rtc/callback", "", h.HandleTencentRTCCallback) r.auth("/files/upload", "", h.UploadFile) r.auth("/files/avatar/upload", "", h.UploadAvatar) r.profile("/devices/push-token", "", h.HandlePushToken) } func (r routes) registerUserRoutes() { h := r.config.User r.public("/users/by-display-user-id/{display_user_id}", "", h.ResolveDisplayUserID) r.profile("/users/profiles:batch", "", h.BatchUserProfiles) r.profile("/users/room-display-profiles:batch", http.MethodGet, h.BatchRoomDisplayProfiles) r.profile("/users/me/overview", "", h.GetMyOverview) r.auth("/users/me/identity", "", h.GetMyIdentity) r.profile("/users/me/host-identity", "", h.GetMyHostIdentity) r.profile("/users/me/role-summary", "", h.GetMyRoleSummary) r.auth("/users/me/onboarding/complete", "", h.CompleteMyOnboarding) r.profile("/users/me/profile/update", "", h.UpdateMyProfile) r.profile("/users/me/country/change", "", h.ChangeMyCountry) r.auth("/users/me/display-id/change", "", h.ChangeMyDisplayUserID) r.auth("/users/me/display-id/pretty/apply", "", h.ApplyMyPrettyDisplayUserID) r.profile("/users/me/visitors", http.MethodGet, h.ListMyProfileVisitors) r.profile("/users/me/following", http.MethodGet, h.ListMyFollowing) r.profile("/users/me/friends", http.MethodGet, h.ListMyFriends) r.profile("/users/me/friend-requests", http.MethodGet, h.ListMyFriendApplications) r.profile("/users/me", "", h.GetMyProfile) r.profile("/users/me/resources", "", h.ListMyResources) r.profile("/users/me/resources/{resource_id}/equip", "", h.EquipMyResource) r.profile("/users/{user_id}/{action...}", "", h.UserSocialAction) } func (r routes) registerManagerRoutes() { h := r.config.Manager r.profile("/manager-center/resource-grants/resources", http.MethodGet, h.ListManagerGrantResources) r.profile("/manager-center/resource-grants", http.MethodPost, h.GrantManagerResource) r.profile("/business/users/lookup", http.MethodGet, h.LookupBusinessUsers) } func (r routes) registerRoomRoutes() { h := r.config.Room r.profile("/rooms/me", http.MethodGet, h.GetMyRoom) r.profile("/rooms/feeds", http.MethodGet, h.ListRoomFeeds) r.profile("/rooms", http.MethodGet, h.ListRooms) r.profile("/rooms/current", http.MethodGet, h.GetCurrentRoom) r.profile("/rooms/snapshot", http.MethodGet, h.GetRoomSnapshot) r.profile("/rooms/{room_id}/detail", http.MethodGet, h.GetRoomDetail) r.profile("/rooms/{room_id}/online-users", http.MethodGet, h.ListRoomOnlineUsers) r.profile("/rooms/{room_id}/gift-panel", http.MethodGet, h.GetRoomGiftPanel) r.profile("/rooms/create", http.MethodPost, h.CreateRoom) r.profile("/rooms/profile/update", http.MethodPost, h.UpdateRoomProfile) r.profile("/rooms/join", http.MethodPost, h.JoinRoom) r.profile("/rooms/heartbeat", http.MethodPost, h.RoomHeartbeat) r.profile("/rooms/leave", http.MethodPost, h.LeaveRoom) r.profile("/rooms/close", http.MethodPost, h.CloseRoom) r.profile("/rooms/mic/up", http.MethodPost, h.MicUp) r.profile("/rooms/mic/down", http.MethodPost, h.MicDown) r.profile("/rooms/mic/change", http.MethodPost, h.ChangeMicSeat) r.profile("/rooms/mic/publishing/confirm", http.MethodPost, h.ConfirmMicPublishing) r.profile("/rooms/mic/mute", http.MethodPost, h.SetMicMute) r.profile("/rooms/mic/lock", http.MethodPost, h.SetMicSeatLock) r.profile("/rooms/chat/enabled", http.MethodPost, h.SetChatEnabled) r.profile("/rooms/admin/set", http.MethodPost, h.SetRoomAdmin) r.profile("/rooms/host/transfer", http.MethodPost, h.TransferRoomHost) r.profile("/rooms/user/mute", http.MethodPost, h.MuteUser) r.profile("/rooms/user/kick", http.MethodPost, h.KickUser) r.profile("/rooms/user/unban", http.MethodPost, h.UnbanUser) r.profile("/rooms/gift/send", http.MethodPost, h.SendGift) } func (r routes) registerMessageRoutes() { h := r.config.Message r.profile("/messages/tabs", "", h.ListMessageTabs) r.profile("/messages/read-all", "", h.MarkInboxSectionRead) r.profile("/messages/{message_id}/read", "", h.MarkInboxMessageReadPath) r.profile("/messages/{message_id}", "", h.DeleteInboxMessagePath) r.profile("/messages", "", h.ListInboxMessages) } func (r routes) registerTaskRoutes() { h := r.config.Task r.profile("/tasks/tabs", http.MethodGet, h.ListTaskTabs) r.profile("/tasks/claim", http.MethodPost, h.ClaimTaskReward) } func (r routes) registerWalletRoutes() { h := r.config.Wallet r.profile("/wallet/me/overview", http.MethodGet, h.GetWalletOverview) r.profile("/wallet/me/balances", "", h.GetMyBalances) r.profile("/wallet/recharge/products", http.MethodGet, h.ListRechargeProducts) r.profile("/wallet/diamond-exchange/config", http.MethodGet, h.GetDiamondExchangeConfig) r.profile("/wallet/withdrawals/apply", http.MethodPost, h.ApplyWithdrawal) r.profile("/wallet/transactions", http.MethodGet, h.ListWalletTransactions) r.profile("/wallet/coin-seller/transfer", "", h.TransferCoinFromSeller) } func (r routes) registerVIPRoutes() { h := r.config.VIP r.profile("/vip/me", http.MethodGet, h.GetMyVIP) r.profile("/vip/packages", http.MethodGet, h.ListVIPPackages) r.profile("/vip/purchase", http.MethodPost, h.PurchaseVIP) } func (r routes) registerGameRoutes() { h := r.config.Game r.profile("/games", http.MethodGet, h.ListGames) r.profile("/games/{game_id}/launch", http.MethodPost, h.LaunchGame) r.public("/game-callbacks/{platform_code}/{operation}", http.MethodPost, h.HandleCallback) }