Echo!
This commit is contained in:
parent
d84eaeb9ca
commit
983c11a162
10 changed files with 95 additions and 116 deletions
|
@ -3,11 +3,9 @@ package api
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/uptrace/bunrouter"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func Ping(w http.ResponseWriter, req bunrouter.Request) error {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("Pong!"))
|
||||
return nil
|
||||
func Ping(c echo.Context) error {
|
||||
return c.String(http.StatusOK, "Pong!")
|
||||
}
|
||||
|
|
24
api/sse.go
24
api/sse.go
|
@ -3,28 +3,26 @@ package api
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/uptrace/bunrouter"
|
||||
"github.com/labstack/echo/v4"
|
||||
"goth.stack/lib"
|
||||
)
|
||||
|
||||
func SSE(w http.ResponseWriter, req bunrouter.Request) error {
|
||||
queryParams := req.URL.Query()
|
||||
channel := queryParams.Get("channel")
|
||||
func SSE(c echo.Context) error {
|
||||
channel := c.QueryParam("channel")
|
||||
if channel == "" {
|
||||
channel = "default"
|
||||
}
|
||||
|
||||
// Use the request context, which is cancelled when the client disconnects
|
||||
ctx := req.Context()
|
||||
ctx := c.Request().Context()
|
||||
|
||||
pubsub, _ := lib.Subscribe(lib.RedisClient, channel)
|
||||
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
w.Header().Set("Connection", "keep-alive")
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
c.Response().Header().Set(echo.HeaderContentType, "text/event-stream")
|
||||
c.Response().Header().Set(echo.HeaderConnection, "keep-alive")
|
||||
c.Response().Header().Set(echo.HeaderCacheControl, "no-cache")
|
||||
|
||||
// Create a ticker that fires every 15 seconds
|
||||
ticker := time.NewTicker(30 * time.Second)
|
||||
|
@ -37,10 +35,10 @@ func SSE(w http.ResponseWriter, req bunrouter.Request) error {
|
|||
return nil
|
||||
case <-ticker.C:
|
||||
// Every 30 seconds, send a comment to keep the connection alive
|
||||
if _, err := w.Write([]byte(": keep-alive\n\n")); err != nil {
|
||||
if _, err := c.Response().Write([]byte(": keep-alive\n\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
w.(http.Flusher).Flush()
|
||||
c.Response().Flush()
|
||||
default:
|
||||
// Handle incoming messages as before
|
||||
msg, err := pubsub.ReceiveMessage(ctx)
|
||||
|
@ -50,11 +48,11 @@ func SSE(w http.ResponseWriter, req bunrouter.Request) error {
|
|||
}
|
||||
|
||||
data := fmt.Sprintf("data: %s\n\n", msg.Payload)
|
||||
if _, err := w.Write([]byte(data)); err != nil {
|
||||
if _, err := c.Response().Write([]byte(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.(http.Flusher).Flush()
|
||||
c.Response().Flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,25 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/uptrace/bunrouter"
|
||||
"github.com/labstack/echo/v4"
|
||||
"goth.stack/lib"
|
||||
)
|
||||
|
||||
func SSEDemoSend(w http.ResponseWriter, req bunrouter.Request) error {
|
||||
// Get query parameters
|
||||
queryParams := req.URL.Query()
|
||||
|
||||
// Get channel from query parameters
|
||||
channel := queryParams.Get("channel")
|
||||
func SSEDemoSend(c echo.Context) error {
|
||||
channel := c.QueryParam("channel")
|
||||
if channel == "" {
|
||||
channel = "default"
|
||||
}
|
||||
|
||||
// Get message from query parameters, form value, or request body
|
||||
message := queryParams.Get("message")
|
||||
message := c.QueryParam("message")
|
||||
if message == "" {
|
||||
message = req.PostFormValue("message")
|
||||
message = c.FormValue("message")
|
||||
if message == "" {
|
||||
var body map[string]string
|
||||
err := json.NewDecoder(req.Body).Decode(&body)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
if err := c.Bind(&body); err != nil {
|
||||
return err
|
||||
}
|
||||
message = body["message"]
|
||||
|
@ -34,18 +27,11 @@ func SSEDemoSend(w http.ResponseWriter, req bunrouter.Request) error {
|
|||
}
|
||||
|
||||
if message == "" {
|
||||
errMsg := map[string]string{"error": "message parameter is required"}
|
||||
errMsgBytes, _ := json.Marshal(errMsg)
|
||||
http.Error(w, string(errMsgBytes), http.StatusBadRequest)
|
||||
return nil
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "message parameter is required"})
|
||||
}
|
||||
|
||||
// Send message
|
||||
lib.SendSSE("default", message)
|
||||
|
||||
statusMsg := map[string]string{"status": "message sent"}
|
||||
statusMsgBytes, _ := json.Marshal(statusMsg)
|
||||
w.Write(statusMsgBytes)
|
||||
|
||||
return nil
|
||||
return c.JSON(http.StatusOK, map[string]string{"status": "message sent"})
|
||||
}
|
||||
|
|
18
go.mod
18
go.mod
|
@ -13,28 +13,28 @@ require (
|
|||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
go.opentelemetry.io/otel v1.22.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.22.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/alecthomas/assert/v2 v2.4.1
|
||||
github.com/atridadl/bmw v1.0.0
|
||||
github.com/go-redis/redismock/v9 v9.2.0
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/labstack/echo/v4 v4.11.4
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/redis/go-redis/v9 v9.4.0
|
||||
github.com/resendlabs/resend-go v1.7.0
|
||||
github.com/unrolled/secure v1.14.0 // indirect
|
||||
github.com/uptrace/bunrouter v1.0.21
|
||||
github.com/uptrace/bunrouter/extra/reqlog v1.0.21
|
||||
github.com/yuin/goldmark v1.6.0
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||
golang.org/x/net v0.20.0 // indirect
|
||||
|
|
32
go.sum
32
go.sum
|
@ -6,8 +6,6 @@ github.com/alecthomas/chroma/v2 v2.12.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurG
|
|||
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||
github.com/alecthomas/repr v0.3.0 h1:NeYzUPfjjlqHY4KtzgKJiWd6sVq2eNUPTi34PiFGjY8=
|
||||
github.com/alecthomas/repr v0.3.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/atridadl/bmw v1.0.0 h1:f0M3D+B5T7kqzswJgHKTBlVw1CgF78xqlfwD6VRub9o=
|
||||
github.com/atridadl/bmw v1.0.0/go.mod h1:LHXSDXKjmOvPXgDv32CDeu1nTmT+luIF+YR9xmqPvEw=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
|
@ -23,22 +21,22 @@ github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55k
|
|||
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
||||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw=
|
||||
github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8=
|
||||
github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
|
@ -60,21 +58,17 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/unrolled/secure v1.14.0 h1:u9vJTU/pR4Bny0ntLUMxdfLtmIRGvQf2sEFuA0TG9AE=
|
||||
github.com/unrolled/secure v1.14.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
|
||||
github.com/uptrace/bunrouter v1.0.21 h1:HXarvX+N834sXyHpl+I/TuE11m19kLW/qG5u3YpHUag=
|
||||
github.com/uptrace/bunrouter v1.0.21/go.mod h1:TwT7Bc0ztF2Z2q/ZzMuSVkcb/Ig/d3MQeP2cxn3e1hI=
|
||||
github.com/uptrace/bunrouter/extra/reqlog v1.0.21 h1:k9ebZATe9NOBUrPcMYJAQ2OMb62ERRN7qfwNwoa6Kxs=
|
||||
github.com/uptrace/bunrouter/extra/reqlog v1.0.21/go.mod h1:j+pXrYzYe3OxTzFb4f/f2JL+CVoGVi1QJJiU0YKSUlw=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
|
||||
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
|
||||
go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y=
|
||||
go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI=
|
||||
go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0=
|
||||
go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -83,6 +77,8 @@ golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
|||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
|
|
57
main.go
57
main.go
|
@ -2,47 +2,52 @@ package main
|
|||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
|
||||
"goth.stack/api"
|
||||
"goth.stack/pages"
|
||||
|
||||
"github.com/atridadl/bmw"
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/uptrace/bunrouter"
|
||||
"github.com/uptrace/bunrouter/extra/reqlog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
godotenv.Load(".env")
|
||||
// Load environment variables
|
||||
err := godotenv.Load(".env")
|
||||
if err != nil {
|
||||
log.Fatal("Error loading .env file")
|
||||
}
|
||||
|
||||
// Initialize router
|
||||
router := bunrouter.New(
|
||||
bunrouter.Use(reqlog.NewMiddleware(), bmw.RequestID, bmw.SecureHeaders),
|
||||
)
|
||||
// Initialize Echo router
|
||||
e := echo.New()
|
||||
|
||||
// Middleware
|
||||
e.Use(middleware.Logger())
|
||||
e.Use(middleware.Recover())
|
||||
e.Pre(middleware.RemoveTrailingSlash())
|
||||
e.Use(middleware.Logger())
|
||||
e.Use(middleware.RequestID())
|
||||
e.Use(middleware.Secure())
|
||||
e.Use(middleware.GzipWithConfig(middleware.GzipConfig{
|
||||
Level: 5,
|
||||
}))
|
||||
e.Use(middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(50)))
|
||||
|
||||
// Static server
|
||||
fs := http.FileServer(http.Dir("public"))
|
||||
|
||||
router.GET("/public/*filepath", func(w http.ResponseWriter, req bunrouter.Request) error {
|
||||
http.StripPrefix("/public", fs).ServeHTTP(w, req.Request)
|
||||
return nil
|
||||
})
|
||||
e.Static("/public", "public")
|
||||
|
||||
// Page routes
|
||||
rateLimiter := bmw.NewRateLimiter(50)
|
||||
pageGroup := router.NewGroup("", bunrouter.Use(rateLimiter.RateLimit))
|
||||
pageGroup.GET("/", pages.Home)
|
||||
pageGroup.GET("/blog", pages.Blog)
|
||||
pageGroup.GET("/post/:post", pages.Post)
|
||||
pageGroup.GET("/sse", pages.SSEDemo)
|
||||
e.GET("/", pages.Home)
|
||||
e.GET("/blog", pages.Blog)
|
||||
e.GET("/post/:post", pages.Post)
|
||||
e.GET("/sse", pages.SSEDemo)
|
||||
|
||||
// API Routes:
|
||||
apiGroup := router.NewGroup("/api")
|
||||
apiGroup := e.Group("/api")
|
||||
apiGroup.GET("/ping", api.Ping)
|
||||
|
||||
apiGroup.GET("/sse", api.SSE)
|
||||
apiGroup.POST("/sendsse", api.SSEDemoSend)
|
||||
|
||||
log.Fatal(http.ListenAndServe(":3000", router))
|
||||
// Start server
|
||||
e.Logger.Fatal(e.Start(":3000"))
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/uptrace/bunrouter"
|
||||
"github.com/labstack/echo/v4"
|
||||
"goth.stack/lib"
|
||||
)
|
||||
|
||||
|
@ -16,19 +16,19 @@ type BlogProps struct {
|
|||
Posts []lib.CardLink
|
||||
}
|
||||
|
||||
func Blog(w http.ResponseWriter, req bunrouter.Request) error {
|
||||
func Blog(c echo.Context) error {
|
||||
var posts []lib.CardLink
|
||||
|
||||
files, err := os.ReadDir("./content/")
|
||||
if err != nil {
|
||||
http.Error(w, "There was an issue finding posts!", http.StatusInternalServerError)
|
||||
http.Error(c.Response().Writer, "There was an issue finding posts!", http.StatusInternalServerError)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
frontMatter, err := lib.ExtractFrontMatter(file, "./content/")
|
||||
if err != nil {
|
||||
http.Error(w, "There was an issue rendering the posts!", http.StatusInternalServerError)
|
||||
http.Error(c.Response().Writer, "There was an issue rendering the posts!", http.StatusInternalServerError)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -62,5 +62,5 @@ func Blog(w http.ResponseWriter, req bunrouter.Request) error {
|
|||
partials := []string{"header", "navitems", "cardlinks"}
|
||||
|
||||
// Render the template
|
||||
return lib.RenderTemplate(w, "base", partials, props)
|
||||
return lib.RenderTemplate(c.Response().Writer, "base", partials, props)
|
||||
}
|
||||
|
|
|
@ -2,9 +2,8 @@ package pages
|
|||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"github.com/uptrace/bunrouter"
|
||||
"github.com/labstack/echo/v4"
|
||||
"goth.stack/lib"
|
||||
)
|
||||
|
||||
|
@ -16,7 +15,7 @@ type HomeProps struct {
|
|||
SupportLink string
|
||||
}
|
||||
|
||||
func Home(w http.ResponseWriter, req bunrouter.Request) error {
|
||||
func Home(c echo.Context) error {
|
||||
socials := []lib.IconLink{
|
||||
{
|
||||
Name: "Email",
|
||||
|
@ -135,6 +134,5 @@ func Home(w http.ResponseWriter, req bunrouter.Request) error {
|
|||
partials := []string{"header", "navitems"}
|
||||
|
||||
// Render the template
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return lib.RenderTemplate(w, "base", partials, props)
|
||||
return lib.RenderTemplate(c.Response().Writer, "base", partials, props)
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"os"
|
||||
|
||||
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
|
||||
"github.com/uptrace/bunrouter"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/yuin/goldmark"
|
||||
highlighting "github.com/yuin/goldmark-highlighting/v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
@ -21,26 +21,26 @@ type PostProps struct {
|
|||
Tags []string
|
||||
}
|
||||
|
||||
func Post(w http.ResponseWriter, req bunrouter.Request) error {
|
||||
postName := req.Param("post")
|
||||
func Post(c echo.Context) error {
|
||||
postName := c.Param("post")
|
||||
|
||||
filePath := "content/" + postName + ".md"
|
||||
|
||||
md, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
http.Error(w, "This post does not exist!", http.StatusNotFound)
|
||||
http.Error(c.Response().Writer, "This post does not exist!", http.StatusNotFound)
|
||||
return nil
|
||||
}
|
||||
|
||||
frontmatterBytes, content, err := lib.SplitFrontmatter(md)
|
||||
if err != nil {
|
||||
http.Error(w, "There was an issue rendering this post!", http.StatusInternalServerError)
|
||||
http.Error(c.Response().Writer, "There was an issue rendering this post!", http.StatusInternalServerError)
|
||||
return nil
|
||||
}
|
||||
|
||||
var frontmatter lib.FrontMatter
|
||||
if err := yaml.Unmarshal(frontmatterBytes, &frontmatter); err != nil {
|
||||
http.Error(w, "There was an issue rendering this post!", http.StatusInternalServerError)
|
||||
http.Error(c.Response().Writer, "There was an issue rendering this post!", http.StatusInternalServerError)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ func Post(w http.ResponseWriter, req bunrouter.Request) error {
|
|||
)
|
||||
|
||||
if err := markdown.Convert(content, &buf); err != nil {
|
||||
http.Error(w, "There was an issue rendering this post!", http.StatusInternalServerError)
|
||||
http.Error(c.Response().Writer, "There was an issue rendering this post!", http.StatusInternalServerError)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -72,5 +72,5 @@ func Post(w http.ResponseWriter, req bunrouter.Request) error {
|
|||
partials := []string{"header", "navitems"}
|
||||
|
||||
// Render the template
|
||||
return lib.RenderTemplate(w, "post", partials, props)
|
||||
return lib.RenderTemplate(c.Response().Writer, "base", partials, props)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
package pages
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/uptrace/bunrouter"
|
||||
"github.com/labstack/echo/v4"
|
||||
"goth.stack/lib"
|
||||
)
|
||||
|
||||
func SSEDemo(w http.ResponseWriter, req bunrouter.Request) error {
|
||||
func SSEDemo(c echo.Context) error {
|
||||
// Specify the partials used by this page
|
||||
partials := []string{"header", "navitems"}
|
||||
|
||||
// Render the template
|
||||
return lib.RenderTemplate(w, "base", partials, nil)
|
||||
return lib.RenderTemplate(c.Response().Writer, "base", partials, nil)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue