From e2167e0b2953d2ce4ca5f30565d62efa44814caa Mon Sep 17 00:00:00 2001 From: Doug Black Date: Sat, 25 Jan 2014 14:19:04 -0800 Subject: better practices --- core.go | 80 +++++++++++++++++++++++++++++++++++++++++++---------------- http.go | 28 ++++++++++++--------- tests/test.go | 20 +++------------ 3 files changed, 79 insertions(+), 49 deletions(-) diff --git a/core.go b/core.go index e0e4a8a..5804b30 100644 --- a/core.go +++ b/core.go @@ -1,14 +1,24 @@ package sleepy import ( + "encoding/json" + "fmt" "net/http" + "net/url" +) + +const ( + GET = "GET" + POST = "POST" + PUT = "PUT" + DELETE = "DELETE" ) type Resource interface { - Get(map[string][]string) string - Post(map[string][]string) string - Put(map[string][]string) string - Delete(map[string][]string) string + Get(values ...url.Values) (int, interface{}) + Post(values ...url.Values) (int, interface{}) + Put(values ...url.Values) (int, interface{}) + Delete(values ...url.Values) (int, interface{}) } type Route struct { @@ -33,27 +43,55 @@ func (api *Api) matchResource(path string) Resource { return nil } -func (api *Api) dispatchRequest(request *http.Request, resource Resource) string { - method := request.Method +func (api *Api) Abort(statusCode int) (int, interface{}) { + return statusCode, map[string]string{"error": "Aborted."} +} + +type HandleFunc func(http.ResponseWriter, *http.Request) + +func (api *Api) requestHandler(resource Resource) HandleFunc { + return func(rw http.ResponseWriter, request *http.Request) { + + var code int + var data interface{} + var content []byte + + method := request.Method + + if request.ParseForm() == nil { + code, data = api.Abort(500) + } + + values := request.Form + + switch method { + case GET: + code, data = resource.Get(values) + case POST: + code, data = resource.Post(values) + case PUT: + code, data = resource.Put(values) + case DELETE: + code, data = resource.Delete(values) + default: + code, data = 405, map[string]string{"error": "Not implemented!"} + } - switch method { - case "GET": - return resource.Get(nil) - case "POST": - return resource.Post(nil) - case "PUT": - return resource.Put(nil) - case "DELETE": - return resource.Delete(nil) + content, err := json.Marshal(data) + if err != nil { + content, _ = json.Marshal(map[string]string{"error": "Bad response."}) + } + + rw.WriteHeader(code) + rw.Write(content) } - return "Not implemented!" } -func (api *Api) HandleRequest(request *http.Request) string { - resource := api.matchResource(request.URL.Path) - return api.dispatchRequest(request, resource) +func (api *Api) AddResource(resource Resource, path string) { + http.HandleFunc(path, api.requestHandler(resource)) } -func (api *Api) AddResource(resource Resource, path string) { - api.routes = append(api.routes, Route{resource, path}) +func (api *Api) Start(port int) { + portString := fmt.Sprintf(":%d", port) + http.ListenAndServe(portString, nil) } diff --git a/http.go b/http.go index c02c123..2c64348 100644 --- a/http.go +++ b/http.go @@ -1,24 +1,28 @@ package sleepy +import ( + "net/url" +) + type ( - GetNotSupported struct {} - PostNotSupported struct {} - PutNotSupported struct {} - DeleteNotSupported struct {} + GetNotSupported struct{} + PostNotSupported struct{} + PutNotSupported struct{} + DeleteNotSupported struct{} ) -func (GetNotSupported) Get(map[string][]string) string { - return "Nope." +func (GetNotSupported) Get(values ...url.Values) (int, interface{}) { + return 405, map[string]string{"error": "Not implemented"} } -func (PostNotSupported) Post(map[string][]string) string { - return "Nope." +func (PostNotSupported) Post(values ...url.Values) (int, interface{}) { + return 405, map[string]string{"error": "Not implemented"} } -func (PutNotSupported) Put(map[string][]string) string { - return "Nope." +func (PutNotSupported) Put(values ...url.Values) (int, interface{}) { + return 405, map[string]string{"error": "Not implemented"} } -func (DeleteNotSupported) Delete(map[string][]string) string { - return "Nope." +func (DeleteNotSupported) Delete(values ...url.Values) (int, interface{}) { + return 405, map[string]string{"error": "Not implemented"} } diff --git a/tests/test.go b/tests/test.go index 055067c..53c7f9e 100644 --- a/tests/test.go +++ b/tests/test.go @@ -1,9 +1,8 @@ package main import ( - "fmt" "sleepy" - "net/http" + "net/url" ) type Bar struct { @@ -12,8 +11,8 @@ type Bar struct { sleepy.DeleteNotSupported } -func (b Bar) Get(map[string][]string) string { - return "Hello" +func (b Bar) Get(values ...url.Values) (int, interface{}) { + return 200, map[string]string{"hello": "goodbye"} } type Baz struct { @@ -22,22 +21,11 @@ type Baz struct { sleepy.DeleteNotSupported } -func (b Baz) Get(map[string][]string) string { - return "Goodbye" -} - func main() { bar := new(Bar) - baz := new(Baz) var api = new(sleepy.Api) api.AddResource(bar, "/bar") - api.AddResource(baz, "/baz") - - request1, _ := http.NewRequest("GET", "https://dougblack.io/bar", nil) - request2, _ := http.NewRequest("GET", "https://dougblack.io/baz", nil) - fmt.Println(api.HandleRequest(request1)) - fmt.Println(api.HandleRequest(request2)) - + api.Start(3000) } -- cgit