Skip to content
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

why marshal enum to json using string but received it with int . #1063

Closed
clearcodecn opened this issue Oct 14, 2019 · 4 comments
Closed

why marshal enum to json using string but received it with int . #1063

clearcodecn opened this issue Oct 14, 2019 · 4 comments

Comments

@clearcodecn
Copy link

clearcodecn commented Oct 14, 2019

I still have a problem!

Bug reports:

Fill in the following sections with explanations of what's gone wrong.

Steps you follow to reproduce the error:

enum Msg {
    Unknown = 0; 
    OK = 1; 
    NotOk = 2; 
}

message testMessage {
    Msg msg = 1;
}

and this will marshal to json like this:

{"msg": "Ok"}

but when I send a request to server using :

{"msg": "Ok"}

this returns failed with message:

unknown value \"Ok\" for enum Msg

What did you expect to happen instead:

it unmarshal message succesed.
I tried Ok , ok, OK it all failed.
but {"msg":1} succeed.

this is my server options.

gwruntime.WithMarshalerOption(gwruntime.MIMEWildcard, &gwruntime.JSONPb{OrigName: true, EmitDefaults: true}),

I can not add the option : EnumsAsInts:true because I would change many code.

I am confused that why marshal to json using string but received it with int .
I generate my pb files using github.com/gogo/protobuf

@johanbrandhorst
Copy link
Collaborator

This seems strange, I think the default unmarshaler should support both of these, so it should parse the string correctly. Have you tried manually using the marshaler with your text to see if that works?

m := &jsonpb.Unmarshaler{}
var v TestMessage
err := m.UnmarshalJSON(bytes.NewBufferString(`{"msg": "Ok"}`), &v)
...

@johanbrandhorst
Copy link
Collaborator

Nevermind, this is because of gogo protobuf's enum registration. You'll need to use the goproto_registration option for this to work. See https://jbrandhorst.com/post/gogoproto/.

@clearcodecn
Copy link
Author

@johanbrandhorst thanks a lot.

@clearcodecn
Copy link
Author

let me repeated how I fixed this:

  • update the latest grpc-gateway and protoc-gen-grpc-gateway protoc-gen-swagger binaries
  • add follow code in my proto files:
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option (gogoproto.goproto_registration) = true;

  • compile the protos(Makefile):
PROTO_DIR = ../proto

PROTO_INCL = -I/usr/local/include \
    -I$(PROTO_DIR) \
    -I./thirdparty

build-protos:
	protoc $(PROTO_INCL) --gogoslick_out=plugins=grpc:pb $(wildcard $(PROTO_DIR)/*.proto)
	protoc $(PROTO_INCL) --grpc-gateway_out=logtostderr=true,allow_patch_feature=false:pb api.proto
  • add customer json marshaler in my grpc server:
go get github.com/gogo/gateway
opts := Mux: []gwruntime.ServeMuxOption{
			gwruntime.WithMarshalerOption(gwruntime.MIMEWildcard, &gateway.JSONPb{
				OrigName:     true,
				EmitDefaults: true,
			}),
		}

mux := gwruntime.NewServeMux(opts...)
... 

that fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants