allow constants for api.Error; update api.Handler signature #12

Merged
xdrm-brackets merged 2 commits from refactor/const-api-errors into 0.3.0 2020-03-28 14:01:09 +00:00
4 changed files with 28 additions and 45 deletions
Showing only changes of commit af09466013 - Show all commits

View File

@ -4,28 +4,23 @@ import (
"strings" "strings"
) )
// HandlerFunc manages an API request // HandlerFn defines the handler signature
type HandlerFunc func(Request, *Response) type HandlerFn func(req Request, res *Response) Error
// Handler is an API handler ready to be bound // Handler is an API handler ready to be bound
type Handler struct { type Handler struct {
path string path string
method string method string
handle HandlerFunc Fn HandlerFn
} }
// NewHandler builds a handler from its http method and path // NewHandler builds a handler from its http method and path
func NewHandler(method, path string, handlerFunc HandlerFunc) *Handler { func NewHandler(method, path string, fn HandlerFn) (*Handler, error) {
return &Handler{ return &Handler{
path: path, path: path,
method: strings.ToUpper(method), method: strings.ToUpper(method),
handle: handlerFunc, Fn: fn,
} }, nil
}
// Handle fires a handler
func (h *Handler) Handle(req Request, res *Response) {
h.handle(req, res)
} }
// GetMethod returns the handler's HTTP method // GetMethod returns the handler's HTTP method

View File

@ -16,29 +16,20 @@ type Response struct {
err Error err Error
} }
// NewResponse creates an empty response. An optional error can be passed as its first argument. // EmptyResponse creates an empty response.
func NewResponse(errors ...Error) *Response { func EmptyResponse() *Response {
res := &Response{ return &Response{
Status: http.StatusOK, Status: http.StatusOK,
Data: make(ResponseData), Data: make(ResponseData),
err: ErrorFailure(), err: ErrorFailure,
Headers: make(http.Header), Headers: make(http.Header),
} }
// optional error
if len(errors) == 1 {
res.err = errors[0]
}
return res
} }
// SetError sets the error from a base error with error arguments. // WithError sets the error from a base error with error arguments.
func (res *Response) SetError(baseError Error, arguments ...interface{}) { func (res *Response) WithError(err Error) *Response {
if len(arguments) > 0 { res.err = err
baseError.SetArguments(arguments[0], arguments[1:]...) return res
}
res.err = baseError
} }
// Error implements the error interface and dispatches to internal error. // Error implements the error interface and dispatches to internal error.

19
http.go
View File

@ -18,7 +18,7 @@ func (server httpServer) ServeHTTP(res http.ResponseWriter, req *http.Request) {
// 1. find a matching service in the config // 1. find a matching service in the config
service := server.config.Find(req) service := server.config.Find(req)
if service == nil { if service == nil {
response := api.NewResponse(api.ErrorUnknownService()) response := api.EmptyResponse().WithError(api.ErrorUnknownService)
response.ServeHTTP(res, req) response.ServeHTTP(res, req)
logError(response) logError(response)
return return
@ -30,7 +30,7 @@ func (server httpServer) ServeHTTP(res http.ResponseWriter, req *http.Request) {
// 3. extract URI data // 3. extract URI data
err := dataset.ExtractURI(req) err := dataset.ExtractURI(req)
if err != nil { if err != nil {
response := api.NewResponse(api.ErrorMissingParam()) response := api.EmptyResponse().WithError(api.ErrorMissingParam)
response.ServeHTTP(res, req) response.ServeHTTP(res, req)
logError(response) logError(response)
return return
@ -39,7 +39,7 @@ func (server httpServer) ServeHTTP(res http.ResponseWriter, req *http.Request) {
// 4. extract query data // 4. extract query data
err = dataset.ExtractQuery(req) err = dataset.ExtractQuery(req)
if err != nil { if err != nil {
response := api.NewResponse(api.ErrorMissingParam()) response := api.EmptyResponse().WithError(api.ErrorMissingParam)
response.ServeHTTP(res, req) response.ServeHTTP(res, req)
logError(response) logError(response)
return return
@ -48,7 +48,7 @@ func (server httpServer) ServeHTTP(res http.ResponseWriter, req *http.Request) {
// 5. extract form/json data // 5. extract form/json data
err = dataset.ExtractForm(req) err = dataset.ExtractForm(req)
if err != nil { if err != nil {
response := api.NewResponse(api.ErrorMissingParam()) response := api.EmptyResponse().WithError(api.ErrorMissingParam)
response.ServeHTTP(res, req) response.ServeHTTP(res, req)
logError(response) logError(response)
return return
@ -68,15 +68,13 @@ func (server httpServer) ServeHTTP(res http.ResponseWriter, req *http.Request) {
// 7. fail if found no handler // 7. fail if found no handler
if foundHandler == nil { if foundHandler == nil {
if found { if found {
r := api.NewResponse() r := api.EmptyResponse().WithError(api.ErrorUncallableService)
r.SetError(api.ErrorUncallableService(), service.Method, service.Pattern)
r.ServeHTTP(res, req) r.ServeHTTP(res, req)
logError(r) logError(r)
return return
} }
r := api.NewResponse() r := api.EmptyResponse().WithError(api.ErrorUnknownService)
r.SetError(api.ErrorUnknownService(), service.Method, service.Pattern)
r.ServeHTTP(res, req) r.ServeHTTP(res, req)
logError(r) logError(r)
return return
@ -93,8 +91,9 @@ func (server httpServer) ServeHTTP(res http.ResponseWriter, req *http.Request) {
apireq.Param = dataset.Data apireq.Param = dataset.Data
// 10. execute // 10. execute
response := api.NewResponse() response := api.EmptyResponse()
foundHandler.Handle(*apireq, response) apiErr := foundHandler.Fn(*apireq, response)
response.WithError(apiErr)
// 11. apply headers // 11. apply headers
res.Header().Set("Content-Type", "application/json; charset=utf-8") res.Header().Set("Content-Type", "application/json; charset=utf-8")

View File

@ -47,13 +47,11 @@ func New(configPath string, dtypes ...datatype.T) (*Server, error) {
} }
// HandleFunc sets a new handler for an HTTP method to a path // HandleFunc sets a new handler for an HTTP method to a path
func (s *Server) HandleFunc(httpMethod, path string, handlerFunc api.HandlerFunc) { func (s *Server) Handle(httpMethod, path string, fn api.HandlerFn) {
handler := api.NewHandler(httpMethod, path, handlerFunc) handler, err := api.NewHandler(httpMethod, path, fn)
s.handlers = append(s.handlers, handler) if err != nil {
} panic(err)
}
// Handle sets a new handler
func (s *Server) Handle(handler *api.Handler) {
s.handlers = append(s.handlers, handler) s.handlers = append(s.handlers, handler)
} }