From ec06b7c4a24b98a29fdd1603c0c9031b61d6abe1 Mon Sep 17 00:00:00 2001 From: Adphi Date: Fri, 3 Jun 2022 13:12:19 +0200 Subject: [PATCH] service: add react web app serving option Signed-off-by: Adphi --- service/options.go | 16 ++++++++++++++++ service/service.go | 5 ++++- service/web.go | 14 ++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/service/options.go b/service/options.go index 1d21c64..e158e8b 100644 --- a/service/options.go +++ b/service/options.go @@ -4,6 +4,7 @@ import ( "context" "crypto/tls" "crypto/x509" + "embed" "fmt" "io/ioutil" "net" @@ -352,6 +353,17 @@ func WithGatewayOpts(opts ...runtime.ServeMuxOption) Option { } } +// WithReactUI add static single page app serving to the http server +// subpath is the path in the read-only file embed.FS to use as root to serve +// static content +func WithReactUI(fs embed.FS, subpath string) Option { + return func(o *options) { + o.reactUI = fs + o.reactUISubPath = subpath + o.hasReactUI = true + } +} + type options struct { ctx context.Context name string @@ -394,6 +406,10 @@ type options struct { gatewayOpts []runtime.ServeMuxOption cors cors.Options + reactUI embed.FS + reactUISubPath string + hasReactUI bool + error error gatewayPrefix string } diff --git a/service/service.go b/service/service.go index ba7db0b..3e2cdd4 100644 --- a/service/service.go +++ b/service/service.go @@ -133,6 +133,9 @@ func newService(opts ...Option) (*service, error) { if err := s.gateway(s.opts.gatewayOpts...); err != nil { return nil, err } + if err := s.reactApp(); err != nil { + return nil, err + } // we do not configure grpc web here as the grpc handlers are not yet registered return s, nil } @@ -203,7 +206,7 @@ func (s *service) run() error { hServer := &http.Server{ Handler: alice.New(s.opts.middlewares...).Then(cors.New(s.opts.cors).Handler(s.opts.mux)), } - if s.opts.Gateway() || s.opts.grpcWeb { + if s.opts.Gateway() || s.opts.grpcWeb || s.opts.hasReactUI { go func() { errs <- hServer.Serve(hList) hServer.Shutdown(s.opts.ctx) diff --git a/service/web.go b/service/web.go index ee9aee3..4dd600b 100644 --- a/service/web.go +++ b/service/web.go @@ -5,6 +5,8 @@ import ( "time" "github.com/improbable-eng/grpc-web/go/grpcweb" + + "go.linka.cloud/grpc/react" ) var defaultWebOptions = []grpcweb.Option{ @@ -33,3 +35,15 @@ func (s *service) grpcWeb(opts ...grpcweb.Option) error { } return nil } + +func (s *service) reactApp() error { + if !s.opts.hasReactUI { + return nil + } + h, err := react.NewHandler(s.opts.reactUI, s.opts.reactUISubPath) + if err != nil { + return err + } + s.opts.mux.Handle("/", h) + return nil +}