diff --git a/go.mod b/go.mod index 84a30be..4c2acd5 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,13 @@ module apigo.cc/go/service go 1.25.0 require ( - apigo.cc/go/cast v1.3.0 + apigo.cc/go/cast v1.3.2 + apigo.cc/go/config v1.3.0 apigo.cc/go/discover v1.3.0 - apigo.cc/go/file v1.3.0 + apigo.cc/go/file v1.3.1 apigo.cc/go/http v1.3.0 apigo.cc/go/id v1.3.0 - apigo.cc/go/log v1.3.0 + apigo.cc/go/log v1.3.2 apigo.cc/go/redis v1.3.0 apigo.cc/go/safe v1.3.0 apigo.cc/go/starter v1.0.1 @@ -18,7 +19,6 @@ require ( ) require ( - apigo.cc/go/config v1.3.0 // indirect apigo.cc/go/crypto v1.3.0 // indirect apigo.cc/go/encoding v1.3.0 // indirect apigo.cc/go/rand v1.3.0 // indirect diff --git a/go.sum b/go.sum index 2eeaaf5..8f70ece 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -apigo.cc/go/cast v1.3.0 h1:ZTcLYijkqZjSWSCSpJUWMfzJYeJKbwKxquKkPrFsROQ= -apigo.cc/go/cast v1.3.0/go.mod h1:lGlwImiOvHxG7buyMWhFzcdvQzmSaoKbmr7bcDfUpHk= +apigo.cc/go/cast v1.3.2 h1:hh9MWDSwh3T/kQdCHjFpjDwHrh2A05Q4wt1AAWs8NBI= +apigo.cc/go/cast v1.3.2/go.mod h1:lGlwImiOvHxG7buyMWhFzcdvQzmSaoKbmr7bcDfUpHk= apigo.cc/go/config v1.3.0 h1:TwI3bv3D+BJrAnFx+o62HQo3FarY2Ge3SCGsKchFYGg= apigo.cc/go/config v1.3.0/go.mod h1:88lqKEBXlIExFKt1geLONVLYyM+QhRVpBe0ok3OEvjI= apigo.cc/go/crypto v1.3.0 h1:rGRrrb5O+4M50X5hVUmJQbXx3l87zzlcgzGtUvZrZL8= @@ -8,14 +8,14 @@ apigo.cc/go/discover v1.3.0 h1:CXuKtAZygU+4TMHtebVkjWyyWmPgoLbsJFdKFGiCOd8= apigo.cc/go/discover v1.3.0/go.mod h1:VMu1qC6AngVFQMdaCwGoq3/PPX0xDnjkG+1AcSA+Zvs= apigo.cc/go/encoding v1.3.0 h1:8jqNHoZBR8vOU/BGsLFebfp1Txa1UxDRpd7YwzIFLJs= apigo.cc/go/encoding v1.3.0/go.mod h1:kT/uUJiuAOkZ4LzUWrUtk/I0iL1D8aatvD+59bDnHBo= -apigo.cc/go/file v1.3.0 h1:xG9FcY3Rv6Br83r9pq9QsIXFrplx4g8ITOkHSzfzXRg= -apigo.cc/go/file v1.3.0/go.mod h1:pYHBlB/XwsrnWpEh7GIFpbiqobrExfiB+rEN8V2d2kY= +apigo.cc/go/file v1.3.1 h1:qHgiJsn1K9DazWRrPoHVnXtp6hDGGsUpAE/4G1bFXqY= +apigo.cc/go/file v1.3.1/go.mod h1:pYHBlB/XwsrnWpEh7GIFpbiqobrExfiB+rEN8V2d2kY= apigo.cc/go/http v1.3.0 h1:1ZweotOuAxTI8wfib9knWYXM2t0POOJ3ezgOKObH3sg= apigo.cc/go/http v1.3.0/go.mod h1:DC3phxBNbt/dOWdhxtffAEYeUs3j6P3BD8e6J8gxU9U= apigo.cc/go/id v1.3.0 h1:Tr2Yj0Rl19lfwW5wBTJ407o/zgo2oVRLE20WWEgJzdE= apigo.cc/go/id v1.3.0/go.mod h1:AFH3kMFwENfXNyijnAFWEhSF1o3y++UBPem1IUlrcxA= -apigo.cc/go/log v1.3.0 h1:61Z80WGN6SnhgxgoR8xuVYIieMdjlJKmf8JX1HXzp0Y= -apigo.cc/go/log v1.3.0/go.mod h1:dz4bSz9BnOgutkUJJZfX3uDDwsMpUxt7WF50mLK9hgE= +apigo.cc/go/log v1.3.2 h1:/m3V4MnlYnCG4XPHpWDsa4cw5suMaDVY1SgaVyjnBSo= +apigo.cc/go/log v1.3.2/go.mod h1:dz4bSz9BnOgutkUJJZfX3uDDwsMpUxt7WF50mLK9hgE= apigo.cc/go/rand v1.3.0 h1:k+UFAhMySwXf+dq8Om9TniZV6fm6gAE0evbrqMEdwQU= apigo.cc/go/rand v1.3.0/go.mod h1:mZ/4Soa3bk+XvDaqPWJuUe1bfEi4eThBj1XmEAuYxsk= apigo.cc/go/redis v1.3.0 h1:3NJE3xPXzhCwL+Mh1iyphFrsKWEuPlY26LHJfMVFSeU= diff --git a/service.go b/service.go index 88c98ba..f6267aa 100644 --- a/service.go +++ b/service.go @@ -151,6 +151,26 @@ func Host(host string) *HostContext { return &HostContext{host: host} } +// Register 注册一个 Web 服务 (使用默认 Host "*") +func Register(method, path string, serviceFunc any) *webServiceType { + return Host("*").Register(method, path, serviceFunc) +} + +// RegisterWebsocket 注册一个 WebSocket 服务 (使用默认 Host "*") +func RegisterWebsocket(path string, serviceFunc any) *websocketServiceType { + return Host("*").WebSocket(path, serviceFunc) +} + +// Proxy 注册一个代理转发 (使用默认 Host "*") +func Proxy(authLevel int, path string, to string) { + Host("*").Proxy(authLevel, path, to) +} + +// Restful 注册一个符合 RESTful 规范的服务结构体 (使用默认 Host "*") +func Restful(authLevel int, path string, serviceStruct any) { + Host("*").Restful(authLevel, path, serviceStruct) +} + func (hc *HostContext) Register(method, path string, serviceFunc any) *webServiceType { s, err := makeCachedService(serviceFunc) if err != nil { @@ -291,6 +311,45 @@ func (hc *HostContext) WebSocket(path string, serviceFunc any) *websocketService return ws } +// Restful 自动根据方法名注册 RESTful 服务 +func (hc *HostContext) Restful(authLevel int, path string, serviceStruct any) { + v := reflect.ValueOf(serviceStruct) + t := v.Type() + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + + for i := 0; i < v.NumMethod(); i++ { + methodName := v.Type().Method(i).Name + var httpMethod string + switch { + case strings.HasPrefix(methodName, "Get"): + httpMethod = "GET" + case strings.HasPrefix(methodName, "Post"): + httpMethod = "POST" + case strings.HasPrefix(methodName, "Put"): + httpMethod = "PUT" + case strings.HasPrefix(methodName, "Delete"): + httpMethod = "DELETE" + case strings.HasPrefix(methodName, "Patch"): + httpMethod = "PATCH" + default: + continue + } + + subPath := strings.ToLower(methodName[len(httpMethod):]) + if subPath == "" { + hc.Register(httpMethod, path, v.Method(i).Interface()).Auth(authLevel) + } else { + fullPath := path + if !strings.HasSuffix(fullPath, "/") { + fullPath += "/" + } + hc.Register(httpMethod, fullPath+subPath, v.Method(i).Interface()).Auth(authLevel) + } + } +} + // webServiceType 链式配置方法 func (s *webServiceType) Auth(level int) *webServiceType { s.authLevel = level