Skip to content
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))
}