influxdb/http
Nathaniel Cook 5bde0b5be6 fix: Update query services to use Request type
Moves idpe.QueryService into platform/query.ProxyQueryService
Splits the Request into ProxyRequest and Request.

Changes query.QueryService and query.AsyncQueryService to use a Request
type. This means that the Compiler interface is consumed by the service
to abstract out transpilation vs Flux compilation vs raw spec.

The transpiler handler is removed.

There are separate http handlers and service implementations for each of
the three query services.

Query logging types are moved into platform.

The ResultIterator now expects Cancel to always be called.

The fluxd binary exposes the query endpoint specified in the swagger
file.
2018-08-08 15:31:35 -06:00
..
influxdb fix(http/influxdb): use dot as delimiter in dbrp 2018-08-07 10:45:14 -04:00
README.md migrate(platform): move public dependencies into platform 2018-05-14 17:12:53 -04:00
assets.go fix(http): fix chronograf build asset paths 2018-07-24 14:25:06 -04:00
auth_service.go revert #442 2018-08-01 14:54:32 -04:00
bucket_service.go revert #442 2018-08-01 14:54:32 -04:00
chronograf_handler.go chore(chronograf): Get Chronograf to "work" as in 1.6.x (w/o Kapacitor) 2018-07-24 15:13:08 -07:00
client.go migrate(platform): move public dependencies into platform 2018-05-14 17:12:53 -04:00
dashboard_service.go revert #442 2018-08-01 14:54:32 -04:00
errors.go fix(http): increase errorHeaderMaxLength 2018-08-01 16:04:36 -07:00
errors_test.go fix(http): increase errorHeaderMaxLength 2018-08-01 16:04:36 -07:00
external_query_handler.go fix: Update query services to use Request type 2018-08-08 15:31:35 -06:00
handler.go feat: add errors to http logging 2018-07-31 14:34:55 -06:00
org_service.go revert #442 2018-08-01 14:54:32 -04:00
platform_handler.go make necessary changes 2018-08-07 16:51:33 -06:00
proxy_query_service.go fix: Update query services to use Request type 2018-08-08 15:31:35 -06:00
query_service.go fix: Update query services to use Request type 2018-08-08 15:31:35 -06:00
server.go fix(http): use a duration literal for the server's shutdown timeout 2018-06-11 12:39:06 -05:00
source_service.go feat(http): add get sources buckets route 2018-08-07 10:45:13 -04:00
status.go feat: Add optional http logging to handler 2018-07-30 16:16:37 -06:00
swagger.yml fix: Update query services to use Request type 2018-08-08 15:31:35 -06:00
task_service.go revert #442 2018-08-01 14:54:32 -04:00
token_parse_test.go fix(http): fix auth header 2018-06-04 15:26:50 -07:00
token_parser.go fix(http): fix auth header 2018-06-04 15:26:50 -07:00
usage_service.go fix(errors): Update Fluxd errors 2018-06-28 16:56:35 -06:00
user_service.go revert #442 2018-08-01 14:54:32 -04:00

README.md

HTTP Handler Style Guide

HTTP Handler

  • Each handler should implement http.Handler
    • This can be done by embedding a httprouter.Router (a light weight HTTP router that supports variables in the routing pattern and matches against the request method)
  • Required services should be exported on the struct
// ThingHandler represents an HTTP API handler for things.
type ThingHandler struct {
	// embedded httprouter.Router as a lazy way to implement http.Handler
	*httprouter.Router

	ThingService         platform.ThingService
	AuthorizationService platform.AuthorizationService

	Logger               *zap.Logger
}

HTTP Handler Constructor

  • Routes should be declared in the constructor
// NewThingHandler returns a new instance of ThingHandler.
func NewThingHandler() *ThingHandler {
	h := &ThingHandler{
		Router: httprouter.New(),
		Logger: zap.Nop(),
	}

	h.HandlerFunc("POST", "/v1/things", h.handlePostThing)
	h.HandlerFunc("GET", "/v1/things", h.handleGetThings)

	return h
}

Route handlers (http.HandlerFuncs)

  • Each route handler should have an associated request struct and decode function
  • The decode function should take a context.Context and an *http.Request and return the associated route request struct
type postThingRequest struct {
	Thing *platform.Thing
}

func decodePostThingRequest(ctx context.Context, r *http.Request) (*postThingRequest, error) {
	t := &platform.Thing{}
	if err := json.NewDecoder(r.Body).Decode(t); err != nil {
		return nil, err
	}

	return &postThingRequest{
		Thing: t,
	}, nil
}
  • Route http.HandlerFuncs should separate the decoding and encoding of HTTP requests/response from actual handler logic
// handlePostThing is the HTTP handler for the POST /v1/things route.
func (h *ThingHandler) handlePostThing(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	req, err := decodePostThingRequest(ctx, r)
	if err != nil {
		errors.EncodeHTTP(ctx, err, w)
		return
	}

	// Do stuff here
	if err := h.ThingService.CreateThing(ctx, req.Thing); err != nil {
		errors.EncodeHTTP(ctx, err, w)
		return
	}

	if err := encodeResponse(ctx, w, http.StatusCreated, req.Thing); err != nil {
		h.Logger.Info("encoding response failed", zap.Error(err))
		return
	}
}
  • http.HandlerFunc's that require particular encoding of http responses should implement an encode response function