Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New http-like HotFunction GO example #691

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions examples/hotfunctions/hello_http/README.md
Original file line number Diff line number Diff line change
@@ -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
}
```
65 changes: 65 additions & 0 deletions examples/hotfunctions/hello_http/func.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
85 changes: 85 additions & 0 deletions examples/hotfunctions/hello_http/func_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
10 changes: 10 additions & 0 deletions examples/hotfunctions/hello_http/hotfunction.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{"route":{
"app_name": "myapp",
"path": "/hothello",
"image": "USERNAME/hchttp",
"memory": 64,
"type": "sync",
"config": null,
"format": "http"
}}