-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add possibility enable emit unpopulated and default values. #6
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright (c) 2024 ESET | ||
// See LICENSE file for redistribution. | ||
|
||
package jsonencoder | ||
|
||
import ( | ||
"google.golang.org/protobuf/encoding/protojson" | ||
"google.golang.org/protobuf/proto" | ||
|
||
jErrors "github.com/juju/errors" | ||
) | ||
|
||
type Config struct { | ||
EmitUnpopulated bool `mapstructure:"emitUnpopulated"` | ||
EmitDefaultValues bool `mapstructure:"emitDefaultValues"` | ||
} | ||
|
||
type Encoder struct { | ||
opts protojson.MarshalOptions | ||
} | ||
|
||
func NewOptions(cfg *Config) Encoder { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename Compare encoder := jsonencoder.NewOptions(cfg) vs encoder := jsonencoder.New(cfg) |
||
return Encoder{ | ||
opts: protojson.MarshalOptions{EmitUnpopulated: cfg.EmitUnpopulated, EmitDefaultValues: cfg.EmitDefaultValues}, | ||
} | ||
} | ||
|
||
func (e Encoder) Format(m proto.Message) (string, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional: Change return value to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional: Rename from Compare jsonResponse, err := jsonEncoder.Format(protoResponse) with jsonResponse, err := jsonEncoder.Encode(protoResponse) |
||
response, err := e.opts.Marshal(m) | ||
if err != nil { | ||
return "", jErrors.Trace(err) | ||
} | ||
|
||
return string(response), nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ import ( | |
"strings" | ||
|
||
grpcClient "github.com/eset/grpc-rest-proxy/pkg/gateway/grpc" | ||
"github.com/eset/grpc-rest-proxy/pkg/service/jsonencoder" | ||
"github.com/eset/grpc-rest-proxy/pkg/service/transformer" | ||
routerPkg "github.com/eset/grpc-rest-proxy/pkg/transport/router" | ||
|
||
|
@@ -22,13 +23,13 @@ import ( | |
"google.golang.org/grpc" | ||
"google.golang.org/grpc/metadata" | ||
"google.golang.org/grpc/status" | ||
"google.golang.org/protobuf/encoding/protojson" | ||
"google.golang.org/protobuf/types/dynamicpb" | ||
) | ||
|
||
type Context struct { | ||
Router *routerPkg.ReloadableRouter | ||
GrcpClient grpcClient.ClientInterface | ||
Encoder jsonencoder.Encoder | ||
} | ||
|
||
type Logger interface { | ||
|
@@ -57,10 +58,10 @@ func getQueryVariables(queryValues url.Values) []transformer.Variable { | |
return queryVariables | ||
} | ||
|
||
func convertRequestToGRPC(route *routerPkg.Match, r *http.Request) (req *dynamicpb.Message, resp *dynamicpb.Message, err error) { | ||
func convertRequestToGRPC(route *routerPkg.Match, r *http.Request) (req *dynamicpb.Message, err error) { | ||
reqBody, err := io.ReadAll(r.Body) | ||
if err != nil { | ||
return nil, nil, jErrors.Trace(err) | ||
return nil, jErrors.Trace(err) | ||
} | ||
r.Body.Close() | ||
|
||
|
@@ -69,11 +70,10 @@ func convertRequestToGRPC(route *routerPkg.Match, r *http.Request) (req *dynamic | |
|
||
req, err = transformer.GetRPCRequest(reqBody, route.GrpcSpec.RequestDesc, route.Params, route.BodyRule) | ||
if err != nil { | ||
return nil, nil, jErrors.Trace(err) | ||
return nil, jErrors.Trace(err) | ||
} | ||
resp = transformer.GetRPCResponse(route.GrpcSpec.ResponseDesc) | ||
|
||
return req, resp, nil | ||
return req, nil | ||
} | ||
|
||
func createRoutingEndpoint(rc *Context, logger Logger) func(w http.ResponseWriter, r *http.Request) { | ||
|
@@ -90,12 +90,13 @@ func createRoutingEndpoint(rc *Context, logger Logger) func(w http.ResponseWrite | |
return | ||
} | ||
|
||
rpcRequest, rpcResponse, err := convertRequestToGRPC(routeMatch, r) | ||
rpcRequest, err := convertRequestToGRPC(routeMatch, r) | ||
if err != nil { | ||
logger.ErrorContext(r.Context(), jErrors.Details(jErrors.Trace(err))) | ||
w.WriteHeader(http.StatusBadRequest) | ||
return | ||
} | ||
rpcResponse := transformer.GetRPCResponse(routeMatch.GrpcSpec.ResponseDesc) | ||
|
||
var header, trailer metadata.MD | ||
err = rc.GrcpClient.Invoke( | ||
|
@@ -116,7 +117,13 @@ func createRoutingEndpoint(rc *Context, logger Logger) func(w http.ResponseWrite | |
} | ||
|
||
transformer.SetRESTHeaders(w.Header(), header, trailer) | ||
fmt.Fprint(w, protojson.Format(rpcResponse)) | ||
response, err := rc.Encoder.Format(rpcResponse) | ||
if err != nil { | ||
logger.ErrorContext(r.Context(), jErrors.Details(jErrors.Trace(err))) | ||
w.WriteHeader(http.StatusInternalServerError) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing |
||
} | ||
|
||
fmt.Fprint(w, response) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using of |
||
w.WriteHeader(http.StatusOK) | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add more detailed description for new cli flags. Imagine user who is using this cli app for the first time.