[feature] Provide a way to custom runtime.ServerMux
liemlhdbeatvn opened this issue · 3 comments
Context: I need a way to add CORS support.
Problem: Currently, there's no way to inject custom runtime.ServerMux
and set it using RestBuilder.
Solution: Add support to inject custom runtime.ServerMux
at
mortar/constructors/partial/httpserver.go
Line 50 in f8601ac
Hi @liemlhdbeatvn, it is actually possible to specify your custom *runtime.ServerMux
.
Here is how to inject a custom *runtime.ServerMux
You probably use this HTTPServerBuilderFxOption
option in your service, usually found in /app/mortar/http.go
file (if you using a provided template).
func HttpServerFxOptions() fx.Option {
return fx.Options(
providers.HTTPServerBuilderFxOption(), // Web Server Builder
...
You will need to replace it with a different one that also returns GRPCWebServiceBuilder
type.
Since this constructor github.com/go-masonry/mortar/constructors/service.go#L23
expect it.
Here you can find an example of how it's currently build github.com/go-masonry/mortar/constructors/partial/httpserver.go
// HTTPServerBuilder true to it's name, it is partially initialized builder.
//
// It uses some default assumptions and configurations, which are mostly good.
// However, if you need to customize your configuration it's better to build yours from scratch
//
func HTTPServerBuilder(deps httpServerDeps) serverInt.GRPCWebServiceBuilder {
builder := server.Builder().SetPanicHandler(deps.panicHandler).SetLogger(deps.Logger.Debug)
host := deps.Config.Get(confkeys.Host).String()
// GRPC port
if grpcPort := deps.Config.Get(confkeys.ExternalGRPCPort); grpcPort.IsSet() {
builder = builder.ListenOn(fmt.Sprintf("%s:%d", host, grpcPort.Int()))
}
// GRPC server interceptors
if len(deps.UnaryInterceptors) > 0 {
interceptorsOption := grpc.ChainUnaryInterceptor(deps.UnaryInterceptors...)
builder = builder.AddGRPCServerOptions(interceptorsOption)
}
builder = deps.buildExternalAPI(builder)
return deps.buildInternalAPI(builder)
}
There are 2 Webservices you can customize: External and Internal.
This AddRESTServerConfiguration() RESTBuilder
method found in GRPCWebServiceBuilder
interface returns a special REST Server RESTBuilder
interface and that one have this SetCustomGRPCGatewayMux(mux *runtime.ServeMux) RESTBuilder
option
Hmm, end up using custom *http.Server
. It's worked now.
@liemlhdbeatvn we added a new feature that might solve what you need in v1.0.26
.
9d0b364
There are 2 new fx groups called externalHttpInterceptors
and internalHttpInterceptors
Here is an example:
func InternalRootHandlersFxOption() fx.Option {
return fx.Provide(
fx.Annotated{
Group: groups.InternalHTTPInterceptors + ",flatten",
Target: func() []serverInt.GRPCGatewayInterceptor {
return []serverInt.GRPCGatewayInterceptor{
func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// check CORS here
// or intercept the root handler by checking r.URL.Path == "/"
handler.ServeHTTP(w, r)
})
},
}
},
})
}