service: add react web app serving option

Signed-off-by: Adphi <philippe.adrien.nousse@gmail.com>
This commit is contained in:
Adphi 2022-06-03 13:12:19 +02:00
parent 9174446b2c
commit ec06b7c4a2
Signed by: adphi
GPG Key ID: 46BE4062DB2397FF
3 changed files with 34 additions and 1 deletions

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"embed"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net" "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 { type options struct {
ctx context.Context ctx context.Context
name string name string
@ -394,6 +406,10 @@ type options struct {
gatewayOpts []runtime.ServeMuxOption gatewayOpts []runtime.ServeMuxOption
cors cors.Options cors cors.Options
reactUI embed.FS
reactUISubPath string
hasReactUI bool
error error error error
gatewayPrefix string gatewayPrefix string
} }

View File

@ -133,6 +133,9 @@ func newService(opts ...Option) (*service, error) {
if err := s.gateway(s.opts.gatewayOpts...); err != nil { if err := s.gateway(s.opts.gatewayOpts...); err != nil {
return nil, err 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 // we do not configure grpc web here as the grpc handlers are not yet registered
return s, nil return s, nil
} }
@ -203,7 +206,7 @@ func (s *service) run() error {
hServer := &http.Server{ hServer := &http.Server{
Handler: alice.New(s.opts.middlewares...).Then(cors.New(s.opts.cors).Handler(s.opts.mux)), 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() { go func() {
errs <- hServer.Serve(hList) errs <- hServer.Serve(hList)
hServer.Shutdown(s.opts.ctx) hServer.Shutdown(s.opts.ctx)

View File

@ -5,6 +5,8 @@ import (
"time" "time"
"github.com/improbable-eng/grpc-web/go/grpcweb" "github.com/improbable-eng/grpc-web/go/grpcweb"
"go.linka.cloud/grpc/react"
) )
var defaultWebOptions = []grpcweb.Option{ var defaultWebOptions = []grpcweb.Option{
@ -33,3 +35,15 @@ func (s *service) grpcWeb(opts ...grpcweb.Option) error {
} }
return nil 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
}