package main import ( "context" "math/rand/v2" "net/http" "os" "sync/atomic" "connectrpc.com/connect" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" homelabv1 "pwa-homelab-mon/gen/homelab/v1" "pwa-homelab-mon/gen/homelab/v1/homelabv1connect" ) type server struct { lucky int64 counter atomic.Int64 } func (s *server) GetLuckyNumber(context.Context, *connect.Request[homelabv1.GetLuckyNumberRequest]) (*connect.Response[homelabv1.GetLuckyNumberResponse], error) { return connect.NewResponse(&homelabv1.GetLuckyNumberResponse{Number: s.lucky}), nil } func (s *server) IncrementCounter(context.Context, *connect.Request[homelabv1.IncrementCounterRequest]) (*connect.Response[homelabv1.IncrementCounterResponse], error) { return connect.NewResponse(&homelabv1.IncrementCounterResponse{Value: s.counter.Add(1)}), nil } func (s *server) SayHello(_ context.Context, req *connect.Request[homelabv1.SayHelloRequest]) (*connect.Response[homelabv1.SayHelloResponse], error) { name := req.Msg.GetName() if name == "" { return nil, connect.NewError(connect.CodeInvalidArgument, os.ErrInvalid) } return connect.NewResponse(&homelabv1.SayHelloResponse{Greeting: "Hello, " + name + "!"}), nil } func main() { svc := &server{lucky: rand.Int64()} e := echo.New() e.HideBanner = true // ConnectRPC handler on the mux (matches /homelab.v1.HomelabService/). mux := http.NewServeMux() mux.Handle(homelabv1connect.NewHomelabServiceHandler(svc)) e.Any("/homelab.v1.HomelabService/*", echo.WrapHandler(mux)) // sw.js must never be cached, otherwise iOS serves a stale service worker. e.Use(func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { if c.Request().URL.Path == "/sw.js" || c.Request().URL.Path == "/manifest.webmanifest" { c.Response().Header().Set("Cache-Control", "no-cache") } return next(c) } }) // Static PWA from web/dist (built by make web); HTML5 mode falls back to index.html for SPA routes. e.Use(middleware.StaticWithConfig(middleware.StaticConfig{ Root: "web/dist", HTML5: true, })) e.Logger.Fatal(e.Start(":8080")) }