From c6bcaaa6b38f03d1f527ebaf6fe58eb3a8beba2d Mon Sep 17 00:00:00 2001 From: auyer Date: Thu, 13 Sep 2018 11:28:22 -0300 Subject: [PATCH 1/2] http style hello _world GO function This example function now implements default request decoding, like if it was part of any http framework. --- examples/hotfunctions/hello_http/func.go | 65 ++++++++++++++ examples/hotfunctions/hello_http/func_test.go | 85 +++++++++++++++++++ .../hotfunctions/hello_http/hotfunction.json | 10 +++ 3 files changed, 160 insertions(+) create mode 100644 examples/hotfunctions/hello_http/func.go create mode 100644 examples/hotfunctions/hello_http/func_test.go create mode 100644 examples/hotfunctions/hello_http/hotfunction.json diff --git a/examples/hotfunctions/hello_http/func.go b/examples/hotfunctions/hello_http/func.go new file mode 100644 index 00000000..ef29e570 --- /dev/null +++ b/examples/hotfunctions/hello_http/func.go @@ -0,0 +1,65 @@ +package main + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "os" +) + +// Person Structure will bind the body accepted by this function +type Person struct { + Name string `json:"Name"` +} + +// handler function deals with the incoming request in http api style +func handler(req *http.Request, res *http.Response) (string, error) { + // If cant read the http request + // Reading the body + p := &Person{Name: "World"} + err := json.NewDecoder(req.Body).Decode(p) + // If the body is not correct + if err != nil || len(p.Name) == 0 { + res.StatusCode = 400 + res.Status = http.StatusText(res.StatusCode) + http.StatusText(res.StatusCode) + return "Invalid Body ", err + } + return fmt.Sprintf("Hello %s", p.Name), err +} + +// main function can be left unchanged in simple applications. You should be able to make changes to +func main() { + for { + // Initializing response structure and the Buffer it will use + res := http.Response{ + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + StatusCode: 200, + Status: "OK", + } + var buf bytes.Buffer + + // reading http request from stdin + req, err := http.ReadRequest(bufio.NewReader(os.Stdin)) + if err != nil { + res.StatusCode = 500 + res.Status = http.StatusText(res.StatusCode) + fmt.Fprintln(&buf, err) + } else { + response, err := handler(req, &res) + if err != nil { + fmt.Fprintf(&buf, err.Error()) + } else { + fmt.Fprintf(&buf, response) + } + } + res.Body = ioutil.NopCloser(&buf) + res.ContentLength = int64(buf.Len()) + res.Write(os.Stdout) + } +} diff --git a/examples/hotfunctions/hello_http/func_test.go b/examples/hotfunctions/hello_http/func_test.go new file mode 100644 index 00000000..a44ee950 --- /dev/null +++ b/examples/hotfunctions/hello_http/func_test.go @@ -0,0 +1,85 @@ +package main + +import ( + "fmt" + "net/http" + "strings" + "testing" +) + +// TestCorrectBody creates a request with a valid body to test the handler +func TestCorrectBody(t *testing.T) { + body := strings.NewReader(`{"Name" : "Auyer"}`) + req, err := http.NewRequest("POST", "http://api:8080/r/hot/hello", body) + if err != nil { + // handle err + } + + req.Header.Set("Content-Type", "application/json") + + res := http.Response{ + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + StatusCode: 200, + Status: "OK", + } + + response, err := handler(req, &res) + if err != nil { + t.Error(err.Error()) + } else if response != `Hello Auyer` { + t.Error("Values do not match " + response) + } +} + +// TestCorrectBody creates a request with an invalid body to test the handler +func TestBadBody(t *testing.T) { + body := strings.NewReader(`{"Name" : `) + req, err := http.NewRequest("POST", "http://api:8080/r/primitives/multiply", body) + if err != nil { + // handle err + } + + req.Header.Set("Content-Type", "application/json") + + res := http.Response{ + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + StatusCode: 200, + Status: "OK", + } + + response, err := handler(req, &res) + if err == nil { + t.Error("Error not detected error " + err.Error()) + } else if response != "Invalid Body " { + t.Error("Returned value different than nil " + response) + } +} + +// TestCorrectBody creates a request with an empty body to test the handler +func TestEmptyBody(t *testing.T) { + fmt.Print("Test") + body := strings.NewReader("{}") + req, err := http.NewRequest("POST", "http://api:8080/r/primitives/multiply", body) + if err != nil { + // handle err + } + + req.Header.Set("Content-Type", "application/json") + + res := http.Response{ + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + StatusCode: 200, + Status: "OK", + } + + response, err := handler(req, &res) + if response != "Hello World" { + t.Error("Returned value different than the Default " + response) + } +} diff --git a/examples/hotfunctions/hello_http/hotfunction.json b/examples/hotfunctions/hello_http/hotfunction.json new file mode 100644 index 00000000..0dccff70 --- /dev/null +++ b/examples/hotfunctions/hello_http/hotfunction.json @@ -0,0 +1,10 @@ +{"route":{ + "app_name": "myapp", + "path": "/hothello", + "image": "USERNAME/hchttp", + "memory": 64, + "type": "sync", + "config": null, + "format": "http" + }} + \ No newline at end of file From 5df8823120dcd693f71e6db0c1501cb1a4e85278 Mon Sep 17 00:00:00 2001 From: auyer Date: Thu, 13 Sep 2018 11:51:56 -0300 Subject: [PATCH 2/2] Hello World HTTP readme --- examples/hotfunctions/hello_http/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 examples/hotfunctions/hello_http/README.md diff --git a/examples/hotfunctions/hello_http/README.md b/examples/hotfunctions/hello_http/README.md new file mode 100644 index 00000000..65fe759a --- /dev/null +++ b/examples/hotfunctions/hello_http/README.md @@ -0,0 +1,17 @@ +# Hello World HTTP Function + +This function is a HTTP style implementation of the basic hello world. + +It is implemented in a way that a handler function will deal with default http requests and responses, similar to how it would work in any other framework. + + +```go + func handler(req *http.Request, res *http.Response) (string, error) { + + decoder := json.NewDecoder(req.Body) // decode data from body + + ... + + return fmt.Sprintf("Content to return to client"), err + } +``` \ No newline at end of file