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

Added Usage Guide & facade for text/template with x-urlencoded-form decoding #171

Open
wants to merge 1 commit 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
56 changes: 56 additions & 0 deletions Usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Typhon Uasge Guide 🐲

## Installation
```bash
go get github.com/monzo/typhon
```

### Define Routes

```go
router := typhon.Router{}

router.GET("/ping", PingHandlerFun)

router.POST("/foo", FooHandlerFun)
```

### Define Server & Add Middlewares
```go
svc := router.Serve().
Filter(typhon.ErrorFilter).
Filter(typhon.H2cFilter)
```

### Run HTTP Server
```go
srv, err := typhon.Listen(
svc,
"localhost:8000",
typhon.WithTimeout(typhon.TimeoutOptions{Read: time.Second * 10}))

log.Printf("👋 Listening on %v", srv.Listener().Addr())
```

### Gracefully Stop Server
```go
done := make(chan os.Signal, 1)
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
<-done
log.Printf("☠️ Shutting down")

c, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
srv.Stop(c)
```

### Define Request Handler Function
```go
func demo(req typhon.Request) typhon.Response {
appHttp := typhon.HttpFacade{Request: req}
return appHttp.ResponseWithView(200, "./demo.html", nil)
}
```

## Description
Typhon is a Go HTTP framework by Monzo that simplifies the process of creating robust and scalable HTTP services. This README provides instructions for installation, defining routes, setting up a server with middleware, running the server, and gracefully shutting it down. Additionally, it includes an example of defining a request handler function.
97 changes: 97 additions & 0 deletions facade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package typhon

package libs

import (
"bytes"
"html/template"
"log"
"net/url"
"strings"

"github.com/monzo/typhon"
)

type HttpFacade struct {
Request typhon.Request
StatusCode int
ResponseBody string
}

func (r HttpFacade) GetFormData() map[string]string {

requestBody, _ := r.Request.BodyBytes(false)
body := string(requestBody)

formData := make(map[string]string)

// Split the body string by '&'
pairs := strings.Split(body, "&")

// Iterate over each key-value pair
for _, pair := range pairs {
// Split the pair into key and value
keyValue := strings.Split(pair, "=")
// Ensure there are exactly two parts (key and value)
if len(keyValue) == 2 {
// Decode the key-value pair and add it to the formData map
key := keyValue[0]
value := keyValue[1]
unescapedPath, err := url.PathUnescape(value)
if err != nil {
log.Println(err)
unescapedPath = value
}
formData[key] = unescapedPath
}
}

return formData
}

func (r HttpFacade) ResponseWithJson(statusCode int, responseBody string) typhon.Response {

instance := typhon.NewResponse(r.Request)
instance.Writer().Header().Set("Content-Type", "application/json")
instance.Writer().Write([]byte(responseBody))
instance.Writer().WriteHeader(statusCode)

return instance
}

func (r HttpFacade) ResponseWithHtml(statusCode int, responseBody string) typhon.Response {

instance := typhon.NewResponse(r.Request)
instance.Writer().Header().Set("Content-Type", "text/html")
instance.Writer().WriteHeader(statusCode)
instance.Writer().Write([]byte(responseBody))

return instance
}

func (r HttpFacade) ResponseWithView(statusCode int, viewPath string, data any) typhon.Response {

instance := typhon.NewResponse(r.Request)
instance.Writer().Header().Set("Content-Type", "text/html")
instance.Writer().WriteHeader(statusCode)
instance.Writer().Write(r.RenderView(viewPath, data))

return instance
}

func (v HttpFacade) RenderView(viewPath string, data any) []byte {

tmpl, err := template.ParseFiles(viewPath)
ErrCheck(err, true)

var resultHTML bytes.Buffer
err = tmpl.Execute(&resultHTML, data)
ErrCheck(err, true)

return resultHTML.Bytes()

}

func (v HttpFacade) RenderViewString(viewPath string, data any) string {
return string(v.RenderView(viewPath, data))
}