packageapiimport("fmt""reflect""sync")typeHandlerFuncanytypePayloadanyvarapiHandlerMap=make(map[string][]HandlerFunc)varmu=sync.RWMutex{}funcRegister(handlers...HandlerFunc){mu.Lock()defermu.Unlock()for_,handler:=rangehandlers{handlerType:=reflect.TypeOf(handler)apiName:=handlerType.In(0).Elem().Name()if_,ok:=apiHandlerMap[apiName];!ok{apiHandlerMap[apiName]=make([]HandlerFunc,0)}apiHandlerMap[apiName]=append(apiHandlerMap[apiName],handler)}}funcDispatch(payloadPayload)error{mu.RLock()defermu.RUnlock()apiName:=reflect.TypeOf(payload).Elem().Name()ifhandlers,ok:=apiHandlerMap[apiName];ok{params:=[]reflect.Value{reflect.ValueOf(payload)}iferr:=callHandlers(handlers,params);err!=nil{returnerr}}else{returnfmt.Errorf("no handler for api '%s'",apiName)}returnnil}funccallHandlers(handlers[]HandlerFunc,params[]reflect.Value)error{for_,handler:=rangehandlers{ret:=reflect.ValueOf(handler).Call(params)e:=ret[0].Interface()ife!=nil{iferr,ok:=e.(error);ok{returnerr}returnfmt.Errorf("expected api-handler to return an error, got '%T'",e)}}returnnil}