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  }