Here is tiny example of how simple and clean "live" things can be in golang using https://data-star.dev
The server clock:
cmd/app/main.go
package main
import (
"log"
"net/http"
"github.com/blinkinglight/clock-data-star/handlers"
"github.com/go-chi/chi/v5"
)
func main() {
router := chi.NewRouter()
handlers.SetupHome(router)
log.Printf("Starting server on :3000")
log.Fatal(http.ListenAndServe(":3000", router))
}
handlers/handlers.go
package handlers
import (
"net/http"
"time"
"github.com/blinkinglight/clock-data-star/web/views"
"github.com/delaneyj/datastar"
"github.com/go-chi/chi/v5"
)
func SetupHome(router chi.Router) {
homeRoute := func(w http.ResponseWriter, r *http.Request) {
views.ClockPage().Render(r.Context(), w)
}
clockRoute := func(w http.ResponseWriter, r *http.Request) {
sse := datastar.NewSSE(w, r)
ticker := time.NewTicker(time.Second)
for {
select {
case <-r.Context().Done():
ticker.Stop()
return
case <-ticker.C:
datastar.RenderFragmentTempl(sse, views.ClockFragment(time.Now().Format("15:04:05")))
}
}
}
router.Get("/", homeRoute)
router.Get("/clock", clockRoute)
}
web/views/page.templ
package views
templ Page() {
<!DOCTYPE html>
<html>
<head>
<script type="module" defer src="https://cdn.jsdelivr.net/npm/@sudodevnull/datastar"></script>
</head>
<body>
<div>
{ children... }
</div>
</body>
</html>
}
and web/views/clock.templ
package views
import "github.com/delaneyj/datastar"
templ ClockPage() {
@Page() {
<div data-on-load={ datastar.GET("/clock") }>
<h1>Clock</h1>
<div id="clock"></div>
</div>
}
}
templ ClockFragment(t string) {
<div id="clock">
{ t }
</div>
}
and thats it.
working example lives here: https://github.com/blinkinglight/clock-data-star
Top comments (0)