github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/api/server/handler.go (about) 1 package server 2 3 import ( 4 "context" 5 "net/http" 6 7 "github.com/tickoalcantara12/micro/v3/service/api" 8 "github.com/tickoalcantara12/micro/v3/service/api/handler" 9 "github.com/tickoalcantara12/micro/v3/service/api/router" 10 "github.com/tickoalcantara12/micro/v3/service/client" 11 "github.com/tickoalcantara12/micro/v3/service/errors" 12 13 aapi "github.com/tickoalcantara12/micro/v3/service/api/handler/api" 14 "github.com/tickoalcantara12/micro/v3/service/api/handler/event" 15 ahttp "github.com/tickoalcantara12/micro/v3/service/api/handler/http" 16 "github.com/tickoalcantara12/micro/v3/service/api/handler/rpc" 17 "github.com/tickoalcantara12/micro/v3/service/api/handler/web" 18 ) 19 20 type metaHandler struct { 21 c client.Client 22 r router.Router 23 ns string 24 } 25 26 var ( 27 // built in handlers 28 handlers = map[string]handler.Handler{ 29 "rpc": rpc.NewHandler(), 30 "web": web.NewHandler(), 31 "http": ahttp.NewHandler(), 32 "event": event.NewHandler(), 33 "api": aapi.NewHandler(), 34 } 35 ) 36 37 // Register a handler 38 func Register(handler string, hd handler.Handler) { 39 handlers[handler] = hd 40 } 41 42 // serverContext 43 type serverContext struct { 44 context.Context 45 domain string 46 client client.Client 47 service *api.Service 48 } 49 50 func (c *serverContext) Service() *api.Service { 51 return c.service 52 } 53 54 func (c *serverContext) Client() client.Client { 55 return c.client 56 } 57 58 func (c *serverContext) Domain() string { 59 return c.domain 60 } 61 62 func (m *metaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 63 service, err := m.r.Route(r) 64 if err != nil { 65 er := errors.InternalServerError(m.ns, err.Error()) 66 w.Header().Set("Content-Type", "application/json") 67 w.WriteHeader(500) 68 w.Write([]byte(er.Error())) 69 return 70 } 71 72 // inject service into context 73 ctx := r.Context() 74 // create a new server context 75 srvContext := &serverContext{ 76 Context: ctx, 77 domain: m.ns, 78 client: m.c, 79 service: service, 80 } 81 // clone request with new context 82 req := r.Clone(srvContext) 83 84 // get the necessary handler 85 hd := service.Endpoint.Handler 86 // retrieve the handler for the request 87 if len(hd) == 0 { 88 hd = "rpc" 89 } 90 91 hdr, ok := handlers[hd] 92 if !ok { 93 // use the catch all rpc handler 94 hdr = handlers["rpc"] 95 } 96 97 // serve the request 98 hdr.ServeHTTP(w, req) 99 } 100 101 // Meta is a http.Handler that routes based on endpoint metadata 102 func Meta(c client.Client, r router.Router, ns string) http.Handler { 103 return &metaHandler{ 104 c: c, 105 r: r, 106 ns: ns, 107 } 108 }