clarity: aicra server request management

This commit is contained in:
Adrien Marquès 2020-04-04 12:05:17 +02:00
parent 5cc3d2d455
commit 60ef4717a8
Signed by: xdrm-brackets
GPG Key ID: D75243CA236D825E
2 changed files with 46 additions and 55 deletions

View File

@ -22,21 +22,16 @@ type Request struct {
} }
// NewRequest builds an interface request from a http.Request // NewRequest builds an interface request from a http.Request
func NewRequest(req *http.Request) (*Request, error) { func NewRequest(req *http.Request) *Request {
// 1. get useful data
uri := normaliseURI(req.URL.Path) uri := normaliseURI(req.URL.Path)
uriparts := strings.Split(uri, "/") uriparts := strings.Split(uri, "/")
// 3. Init request return &Request{
inst := &Request{
URI: uriparts, URI: uriparts,
Scope: nil, Scope: nil,
Request: req, Request: req,
Param: make(RequestParam), Param: make(RequestParam),
} }
return inst, nil
} }
// normaliseURI removes the trailing '/' to always // normaliseURI removes the trailing '/' to always

View File

@ -1,10 +1,10 @@
package aicra package aicra
import ( import (
"log"
"net/http" "net/http"
"git.xdrm.io/go/aicra/api" "git.xdrm.io/go/aicra/api"
"git.xdrm.io/go/aicra/internal/config"
"git.xdrm.io/go/aicra/internal/reqdata" "git.xdrm.io/go/aicra/internal/reqdata"
) )
@ -18,43 +18,18 @@ func (server Server) 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.conf.Find(req) service := server.conf.Find(req)
if service == nil { if service == nil {
response := api.EmptyResponse().WithError(api.ErrorUnknownService) errorHandler(api.ErrorUnknownService)
response.ServeHTTP(res, req)
logError(response)
return return
} }
// 2. build input parameter receiver // 2. extract request data
dataset := reqdata.New(service) dataset, err := extractRequestData(service, *req)
// 3. extract URI data
err := dataset.ExtractURI(req)
if err != nil { if err != nil {
response := api.EmptyResponse().WithError(api.ErrorMissingParam) errorHandler(api.ErrorMissingParam)
response.ServeHTTP(res, req)
logError(response)
return return
} }
// 4. extract query data // 3. find a matching handler
err = dataset.ExtractQuery(req)
if err != nil {
response := api.EmptyResponse().WithError(api.ErrorMissingParam)
response.ServeHTTP(res, req)
logError(response)
return
}
// 5. extract form/json data
err = dataset.ExtractForm(req)
if err != nil {
response := api.EmptyResponse().WithError(api.ErrorMissingParam)
response.ServeHTTP(res, req)
logError(response)
return
}
// 6. find a matching handler
var handler *apiHandler var handler *apiHandler
for _, h := range server.handlers { for _, h := range server.handlers {
if h.Method == service.Method && h.Path == service.Pattern { if h.Method == service.Method && h.Path == service.Pattern {
@ -62,26 +37,16 @@ func (server Server) ServeHTTP(res http.ResponseWriter, req *http.Request) {
} }
} }
// 7. fail if found no handler // 4. fail if found no handler
if handler == nil { if handler == nil {
r := api.EmptyResponse().WithError(api.ErrorUnknownService) errorHandler(api.ErrorUncallableService)
r.ServeHTTP(res, req)
logError(r)
return return
} }
// 8. build api.Request from http.Request // 5. execute
apireq, err := api.NewRequest(req)
if err != nil {
log.Fatal(err)
}
// 9. feed request with scope & parameters
apireq.Scope = service.Scope
apireq.Param = dataset.Data
// 10. execute
returned, apiErr := handler.dyn.Handle(dataset.Data) returned, apiErr := handler.dyn.Handle(dataset.Data)
// 6. build response from returned data
response := api.EmptyResponse().WithError(apiErr) response := api.EmptyResponse().WithError(apiErr)
for key, value := range returned { for key, value := range returned {
@ -93,7 +58,7 @@ func (server Server) ServeHTTP(res http.ResponseWriter, req *http.Request) {
} }
} }
// 11. apply headers // 7. apply headers
res.Header().Set("Content-Type", "application/json; charset=utf-8") res.Header().Set("Content-Type", "application/json; charset=utf-8")
for key, values := range response.Headers { for key, values := range response.Headers {
for _, value := range values { for _, value := range values {
@ -101,6 +66,37 @@ func (server Server) ServeHTTP(res http.ResponseWriter, req *http.Request) {
} }
} }
// 12. write to response
response.ServeHTTP(res, req) response.ServeHTTP(res, req)
} }
func errorHandler(err api.Error) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
r := api.EmptyResponse().WithError(err)
r.ServeHTTP(res, req)
logError(r)
}
}
func extractRequestData(service *config.Service, req http.Request) (*reqdata.Set, error) {
dataset := reqdata.New(service)
// 3. extract URI data
err := dataset.ExtractURI(req)
if err != nil {
return nil, err
}
// 4. extract query data
err = dataset.ExtractQuery(req)
if err != nil {
return nil, err
}
// 5. extract form/json data
err = dataset.ExtractForm(req)
if err != nil {
return nil, err
}
return dataset, nil
}