hackathon/cmd/gw/main.go

77 lines
2.1 KiB
Go

// Command gunk-example-server-gw is a grpc-gateway example implementation for
// the gunk-example-server.
package main
import (
"context"
"flag"
"fmt"
"io"
"net"
"net/http"
"os"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
codequestpb "github.com/hhhapz/codequest/api/v1"
"github.com/kenshaw/redoc"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
"google.golang.org/protobuf/encoding/protojson"
)
func main() {
addr := flag.String("l", "0.0.0.0:8080", "listen address")
endpoint := flag.String("endpoint", "localhost:10000", "grpc endpoint")
flag.Parse()
if err := run(context.Background(), *addr, *endpoint); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}
// run creates and runs the gateway instance.
func run(ctx context.Context, addr, endpoint string) error {
// build gateway mux
gw, opts := runtime.NewServeMux(
runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{
MarshalOptions: protojson.MarshalOptions{
EmitUnpopulated: true,
},
}),
), []grpc.DialOption{grpc.WithInsecure()}
for _, f := range []func(context.Context, *runtime.ServeMux, string, []grpc.DialOption) error{
codequestpb.RegisterAuthServiceHandlerFromEndpoint,
codequestpb.RegisterUserServiceHandlerFromEndpoint,
codequestpb.RegisterQuestServiceHandlerFromEndpoint,
} {
if err := f(ctx, gw, endpoint, opts); err != nil {
return err
}
}
// build mux
mux := http.NewServeMux()
// handle swagger
mux.HandleFunc("/v1/swagger.json", func(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "application/json")
_, _ = res.Write(codequestpb.Swagger)
})
// handle gateway
mux.Handle("/v1/", gw)
// add redoc
if err := redoc.New("/v1/swagger.json", "/", redoc.WithServeMux(mux)).Build(ctx, nil); err != nil {
return err
}
log := grpclog.NewLoggerV2(os.Stderr, io.Discard, os.Stderr)
grpclog.SetLoggerV2(log)
log.Info("Serving gateway on http://", addr)
// listen and serve
l, err := (&net.ListenConfig{}).Listen(ctx, "tcp", addr)
if err != nil {
return err
}
defer l.Close()
return http.Serve(l, mux)
}