// 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) }