* fix: duplicated X-version and X-Build headers for /ping endpoint
Signed-off-by: Jakub Bednar <jakub.bednar@gmail.com>
* chore: change branch to master
* chore: only http/handler.go is responsible for sets headers
Signed-off-by: Jakub Bednar <jakub.bednar@gmail.com>
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.
typeThingHandlerstruct{// embedded httprouter.Router as a lazy way to implement http.Handler
*httprouter.RouterThingServiceplatform.ThingServiceAuthorizationServiceplatform.AuthorizationServiceLogger*zap.Logger}
HTTP Handler Constructor
Routes should be declared in the constructor
// NewThingHandler returns a new instance of ThingHandler.
funcNewThingHandler()*ThingHandler{h:=&ThingHandler{Router:httprouter.New(),Logger:zap.Nop(),}h.HandlerFunc("POST","/api/v2/things",h.handlePostThing)h.HandlerFunc("GET","/api/v2/things",h.handleGetThings)returnh}
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
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 /api/v2/things route.
func(h*ThingHandler)handlePostThing(whttp.ResponseWriter,r*http.Request){ctx:=r.Context()req,err:=decodePostThingRequest(ctx,r)iferr!=nil{EncodeError(ctx,err,w)return}// Do stuff here
iferr:=h.ThingService.CreateThing(ctx,req.Thing);err!=nil{EncodeError(ctx,err,w)return}iferr:=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