diff --git a/api/error.defaults.go b/api/error.defaults.go index b7cf3b0..8c461fc 100644 --- a/api/error.defaults.go +++ b/api/error.defaults.go @@ -48,11 +48,11 @@ var ( // ErrorUncallableService is set when there the requested controller's // implementation (plugin file) is not found/callable - // ErrorUncallableService = func() Error { return Error{202, "uncallable service", nil} } + ErrorUncallableService = func() Error { return Error{202, "uncallable service", nil} } // ErrorUncallableMethod is set when there the requested controller's // implementation does not features the requested method - // ErrorUncallableMethod = func() Error { return Error{203, "uncallable method", nil} } + ErrorUncallableMethod = func() Error { return Error{203, "uncallable method", nil} } // ErrorPermission is set when there is a permission error by default // the api returns a permission error when the current scope (built diff --git a/api/error.go b/api/error.go index 8c69727..af72dd1 100644 --- a/api/error.go +++ b/api/error.go @@ -8,9 +8,9 @@ import ( // These are used by the controllers to set the *execution status* // directly into the response as JSON alongside response output fields. type Error struct { - Code int `json:"error"` + Code int `json:"code"` Reason string `json:"reason"` - Arguments []interface{} `json:"error_args"` + Arguments []interface{} `json:"arguments"` } // Put adds an argument to the error diff --git a/api/response.go b/api/response.go index 7c7cdb3..2b2d96e 100644 --- a/api/response.go +++ b/api/response.go @@ -35,13 +35,16 @@ func (i *Response) GetData(name string) interface{} { return value } -type jsonResponse struct { - Error - ResponseData -} - // MarshalJSON implements the 'json.Marshaler' interface and is used // to generate the JSON representation of the response func (i *Response) MarshalJSON() ([]byte, error) { - return json.Marshal(jsonResponse{i.Err, i.Data}) + fmt := make(map[string]interface{}) + + for k, v := range i.Data { + fmt[k] = v + } + + fmt["error"] = i.Err + + return json.Marshal(fmt) } diff --git a/internal/reqdata/dataset.go b/internal/reqdata/store.go similarity index 93% rename from internal/reqdata/dataset.go rename to internal/reqdata/store.go index 7d197d2..de4d4e5 100644 --- a/internal/reqdata/dataset.go +++ b/internal/reqdata/store.go @@ -44,30 +44,35 @@ type Store struct { } // New creates a new store from an http request. -func New(req *http.Request) *Store { +// URI params is required because it only takes into account after service path +// we do not know in this scope. +func New(uriParams []string, req *http.Request) *Store { ds := &Store{ URI: make([]*Parameter, 0), Get: make(map[string]*Parameter), Form: make(map[string]*Parameter), Set: make(map[string]*Parameter), } - // 1. GET (query) data + + // 1. set URI parameters + ds.setURIParams(uriParams) + + // 2. GET (query) data ds.fetchGet(req) - // 2. We are done if GET method + // 3. We are done if GET method if req.Method == http.MethodGet { return ds } - // 2. POST (body) data + // 4. POST (body) data ds.fetchForm(req) return ds } -// SetURIParameters stores URL orderedURIParams and fills 'Set' -// with creating pointers inside 'Url' -func (i *Store) SetURIParameters(orderedUParams []string) { +// setURIParameters fills 'Set' with creating pointers inside 'Url' +func (i *Store) setURIParams(orderedUParams []string) { for index, value := range orderedUParams { diff --git a/server.go b/server.go index 374cd4e..18b7584 100644 --- a/server.go +++ b/server.go @@ -16,7 +16,7 @@ import ( // Server represents an AICRA instance featuring: type checkers, services type Server struct { services *config.Service - checkers *checker.Set + Checkers *checker.Set handlers []*api.Handler } @@ -28,7 +28,7 @@ func New(configPath string) (*Server, error) { // 1. init instance var i = &Server{ services: nil, - checkers: checker.New(), + Checkers: checker.New(), handlers: make([]*api.Handler, 0), } @@ -81,7 +81,7 @@ func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request) { } // 4. parse every input data from the request - store := reqdata.New(req) + store := reqdata.New(apiRequest.URI[pathIndex:], req) /* (4) Check parameters ---------------------------------------------------------*/ @@ -112,10 +112,10 @@ func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request) { // fail if found no handler if serviceHandler == nil { if serviceFound { - httpError(res, api.ErrorUnknownMethod()) + httpError(res, api.ErrorUncallableMethod()) return } - httpError(res, api.ErrorUnknownService()) + httpError(res, api.ErrorUncallableService()) return } diff --git a/typecheck/builtin/float64.go b/typecheck/builtin/float64.go index 69c4948..8e8e12a 100644 --- a/typecheck/builtin/float64.go +++ b/typecheck/builtin/float64.go @@ -1,6 +1,11 @@ package builtin -import "git.xdrm.io/go/aicra/typecheck" +import ( + "log" + "strconv" + + "git.xdrm.io/go/aicra/typecheck" +) // Float64 checks if a value is a float64 type Float64 struct{} @@ -17,7 +22,24 @@ func (Float64) Checker(typeName string) typecheck.Checker { return nil } return func(value interface{}) bool { - _, isFloat64 := value.(bool) - return isFloat64 + strVal, isString := value.(string) + _, isFloat64 := value.(float64) + + log.Printf("1") + + // raw float + if isFloat64 { + return true + } + + // string float + if !isString { + return false + } + _, err := strconv.ParseFloat(strVal, 64) + if err != nil { + return false + } + return true } } diff --git a/typecheck/builtin/string.go b/typecheck/builtin/string.go index 5bc9fc2..9ae24ab 100644 --- a/typecheck/builtin/string.go +++ b/typecheck/builtin/string.go @@ -7,7 +7,7 @@ import ( "git.xdrm.io/go/aicra/typecheck" ) -var fixedLengthRegex = regexp.MustCompile(`^string\((\d+))$`) +var fixedLengthRegex = regexp.MustCompile(`^string\((\d+)\)$`) var variableLengthRegex = regexp.MustCompile(`^string\((\d+), ?(\d+)\)$`) // String checks if a value is a string diff --git a/util.go b/util.go index 3b75b61..e371623 100644 --- a/util.go +++ b/util.go @@ -4,24 +4,12 @@ import ( "encoding/json" "log" "net/http" - "strings" "git.xdrm.io/go/aicra/api" "git.xdrm.io/go/aicra/internal/config" "git.xdrm.io/go/aicra/internal/reqdata" ) -func (s *Server) findServiceDef(req *api.Request) (serviceDef *config.Service, servicePath string) { - - // 1. try to find definition - serviceDef, pathi := s.services.Browse(req.URI) - - // 2. set service uri - servicePath = strings.Join(req.URI[:pathi], "/") - - return -} - // extractParameters extracts parameters for the request and checks // every single one according to configuration options func (s *Server) extractParameters(store *reqdata.Store, methodParam map[string]*config.Parameter) (map[string]interface{}, api.Error) { @@ -80,7 +68,7 @@ func (s *Server) extractParameters(store *reqdata.Store, methodParam map[string] } /* (7) Check type */ - if s.checkers.Run(param.Type, p.Value) != nil { + if s.Checkers.Run(param.Type, p.Value) != nil { apiError = api.ErrorInvalidParam() apiError.Put(param.Rename)