HttpApiHandlerContainer 추가

This commit is contained in:
2023-09-05 11:43:42 +09:00
parent 821dc5c639
commit 84f56dfc50

View File

@ -20,6 +20,7 @@ import (
"sync/atomic" "sync/atomic"
"syscall" "syscall"
"time" "time"
"unsafe"
"repositories.action2quare.com/ayo/gocommon/flagx" "repositories.action2quare.com/ayo/gocommon/flagx"
"repositories.action2quare.com/ayo/gocommon/logger" "repositories.action2quare.com/ayo/gocommon/logger"
@ -606,3 +607,68 @@ func MakeHttpRequestForLogging(r *http.Request) *http.Request {
r.Body = ib r.Body = ib
return r return r
} }
type apiFuncType func(http.ResponseWriter, *http.Request)
type HttpApiReceiver struct {
methods map[string]apiFuncType
}
func MakeHttpApiReceiver[T any](receiver *T) HttpApiReceiver {
methods := make(map[string]apiFuncType)
tp := reflect.TypeOf(receiver)
name := tp.Elem().Name()
for i := 0; i < tp.NumMethod(); i++ {
method := tp.Method(i)
if method.Type.NumIn() != 3 {
continue
}
if method.Type.In(0) != tp {
continue
}
var w http.ResponseWriter
if method.Type.In(1) != reflect.TypeOf(w) {
continue
}
var r http.Request
if method.Type.In(2) != reflect.TypeOf(&r) {
continue
}
if method.Name == "ServeHTTP" {
continue
}
funcptr := method.Func.Pointer()
p1 := unsafe.Pointer(&funcptr)
p2 := unsafe.Pointer(&p1)
testfunc := (*func(*T, http.ResponseWriter, *http.Request))(p2)
methods[name+"."+method.Name] = func(w http.ResponseWriter, r *http.Request) {
(*testfunc)(receiver, w, r)
}
}
return HttpApiReceiver{
methods: methods,
}
}
type HttpApiHandlerContainer struct {
methods map[string]apiFuncType
}
func (hc *HttpApiHandlerContainer) RegistReceiver(receiver HttpApiReceiver) {
for k, v := range receiver.methods {
logger.Println("http api registered :", k)
hc.methods[k] = v
}
}
func (hc *HttpApiHandlerContainer) HandlerFunc(serveMux *http.ServeMux, prefix string) {
for k, v := range hc.methods {
serveMux.HandleFunc(MakeHttpHandlerPattern(prefix, k), v)
}
}