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  }