github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/access/rest/routes/handler.go (about) 1 package routes 2 3 import ( 4 "net/http" 5 6 "github.com/rs/zerolog" 7 8 "github.com/onflow/flow-go/access" 9 "github.com/onflow/flow-go/engine/access/rest/models" 10 "github.com/onflow/flow-go/engine/access/rest/request" 11 "github.com/onflow/flow-go/engine/access/rest/util" 12 "github.com/onflow/flow-go/model/flow" 13 ) 14 15 // ApiHandlerFunc is a function that contains endpoint handling logic, 16 // it fetches necessary resources and returns an error or response model. 17 type ApiHandlerFunc func( 18 r *request.Request, 19 backend access.API, 20 generator models.LinkGenerator, 21 ) (interface{}, error) 22 23 // Handler is custom http handler implementing custom handler function. 24 // Handler function allows easier handling of errors and responses as it 25 // wraps functionality for handling error and responses outside of endpoint handling. 26 type Handler struct { 27 *HttpHandler 28 backend access.API 29 linkGenerator models.LinkGenerator 30 apiHandlerFunc ApiHandlerFunc 31 } 32 33 func NewHandler( 34 logger zerolog.Logger, 35 backend access.API, 36 handlerFunc ApiHandlerFunc, 37 generator models.LinkGenerator, 38 chain flow.Chain, 39 ) *Handler { 40 handler := &Handler{ 41 backend: backend, 42 apiHandlerFunc: handlerFunc, 43 linkGenerator: generator, 44 HttpHandler: NewHttpHandler(logger, chain), 45 } 46 47 return handler 48 } 49 50 // ServerHTTP function acts as a wrapper to each request providing common handling functionality 51 // such as logging, error handling, request decorators 52 func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 53 // create a logger 54 errLog := h.Logger.With().Str("request_url", r.URL.String()).Logger() 55 56 err := h.VerifyRequest(w, r) 57 if err != nil { 58 return 59 } 60 decoratedRequest := request.Decorate(r, h.Chain) 61 62 // execute handler function and check for error 63 response, err := h.apiHandlerFunc(decoratedRequest, h.backend, h.linkGenerator) 64 if err != nil { 65 h.errorHandler(w, err, errLog) 66 return 67 } 68 69 // apply the select filter if any select fields have been specified 70 response, err = util.SelectFilter(response, decoratedRequest.Selects()) 71 if err != nil { 72 h.errorHandler(w, err, errLog) 73 return 74 } 75 76 // write response to response stream 77 h.jsonResponse(w, http.StatusOK, response, errLog) 78 }