I'm trying to create a microservice app using grpc gateway, but faced with a small problem. When I try to send request to api, my fields initialize as zero-value. It's the first time when I'm trying grpc gateway so the problem can be kinda stupid.
Here's my request:
{
"amount": 20000,
"bill": 1010,
"email": "[email protected]",
"employeeID": 1,
"userID": 1,
"orgID": 1,
"feedback": "good",
"grade": 5,
"isCommissionCompensated": true,
"redirectURL": "https://google.com",
"failRedirectURL": "https://google.com",
"paymentMethod": "CARD"
}
Here's the proto file of grpc gateway
syntax = "proto3";
option go_package = "/paymentProto";
import "google/api/annotations.proto";
package payment;
service PaymentService {
rpc PayIn(PayInRequest) returns(PayInResponse) {
option(google.api.http) = {
post: "/payment/pay_in"
};
}
}
message PayInRequest {
uint64 userID = 1;
uint64 employeeID = 2;
uint64 orgID = 3;
string redirectURL = 4;
string failRedirectURL = 5;
double amount = 6;
string email = 7;
string feedback = 8;
uint32 grade = 9;
bool isCommissionCompensated = 10;
optional double bill = 11;
string paymentMethod = 12;
}
message PayInResponse {
string payInForm = 1;
}
I have a method that initialize my server
func (s *Server) Run() error {
s.MapHandlers()
var eg errgroup.Group
eg.Go(s.RunPaymentGRPC)
eg.Go(s.RunPaymentHTTP)
if err := eg.Wait(); err != nil {
return errors.Wrap(err, "Server.Run")
}
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logger.Info("Shutting down Payment server...")
s.grpcServer.GracefulStop()
logger.Info("Success!")
return nil
}
And 3 methods that initialize the gateway:
func (s *Server) MapHandlers() {
logger.Info("Trying to map handlers...")
paymentUC := paymentUsecase.NewPaymentUC()
paymentHandlers := paymentDelivery.NewHandlers(paymentUC)
paymentProto.RegisterPaymentServiceServer(s.grpcServer, paymentHandlers)
logger.Info("Success!")
}
func (s *Server) RunPaymentHTTP() error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
logger.Info("Trying to run http server")
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
err := paymentProto.RegisterPaymentServiceHandlerFromEndpoint(ctx, s.mux, s.cfg.PaymentServer.Grpc.Host, opts)
if err != nil {
return errors.Wrap(err, "failed to register gRPC gateway")
}
logger.Infof("Serving http on %s", s.cfg.PaymentServer.Http.Host)
if err := http.ListenAndServe(s.cfg.PaymentServer.Http.Host, s.mux); err != nil {
return errors.Wrap(err, "failed to serve")
}
logger.Info("Success!")
return nil
}
func (s *Server) RunPaymentGRPC() error {
lis, err := net.Listen("tcp", s.cfg.PaymentServer.Grpc.Host)
if err != nil {
return errors.Wrapf(err, "failed to listen: %v", s.cfg.PaymentServer.Grpc.Host)
}
logger.Infof("Serving gRPC on %s", s.cfg.PaymentServer.Grpc.Host)
if err := s.grpcServer.Serve(lis); err != nil {
return errors.Wrap(err, "failed to serve gRPC server")
}
return nil
}
And here's the struct that implements my genered proto file code
type PaymentHandlers struct {
paymentUC PaymentUC
paymentProto.UnimplementedPaymentServiceServer
}
func NewHandlers(paymentUC PaymentUC) *PaymentHandlers {
return &PaymentHandlers{
paymentUC: paymentUC,
}
}
func (h *PaymentHandlers) PayIn(
ctx context.Context,
request *paymentProto.PayInRequest,
) (*paymentProto.PayInResponse, error) {
ctx, span := otel.Tracer("api-gateway").Start(ctx, "PaymentHandlers.PayIn")
defer span.End()
return &paymentProto.PayInResponse{
PayInForm: "success",
}, nil
}
And when I try to send request, my genered struct has such fields
What can be the problem? Thank u in advance!
Your service proto is missing the body: "*" which may be causing the issue. Can you try adding it to see if it fixes the issue?
service PaymentService {
rpc PayIn(PayInRequest) returns(PayInResponse) {
option(google.api.http) = {
post: "/payment/pay_in"
body: "*"
};
}
}
As the google api annotation proto mentions:
Any fields in the request message which are not bound by the path template automatically become HTTP query parameters if there is no HTTP request body.
So I suspect your message is getting zero values for the fields because there are no URL query parameters provided and the body annotation is missing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With