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

Question: How can I get JSONPB to omit fields #373

Closed
svperfecta opened this issue Jan 29, 2018 · 8 comments
Closed

Question: How can I get JSONPB to omit fields #373

svperfecta opened this issue Jan 29, 2018 · 8 comments

Comments

@svperfecta
Copy link

Using the gogo/jsonpb package, is there a way to omit a field when marshaling to JSON?

My proto looks like this:

int32 capacity = 13 [(gogoproto.jsontag) = "-"];

My generated file looks like:

Capacity        int32          `protobuf:"varint,13,opt,name=capacity,proto3" json:"-"`

And I use this to marshal:

unmarshaller := &jsonpb.Marshaler{EmitDefaults: true}
json, err := unmarshaller.MarshalToString(s)

I'm probably missing something obvious, but I can't seem to find the right invocation :)

@awalterschulze
Copy link
Member

json tag is still for encoding with the encoding/json package.
This was the old way of encoding to json given a protobuf struct.
As you correctly asserted the jsonpb package is the way to encode protobufs to json now.
I think jsonpb ignoes the json tag in favour of a json= string inside the protobuf tag.
This should be generated with newer versions of protoc.
May I ask which version you are using?

Also if EmitDefaults with jsonpb does not work, you should create an issue on golang/protobuf.
It looks to me like a zero value for Capacity should not marshal to json that includes the field even without using the jsontag.
What happens when you don't use jsontag and use EmitDefaults with the jsonpb package?

@svperfecta
Copy link
Author

Hey @awalterschulze Thanks for the response!

Here's my version of protoc

$ protoc --version
libprotoc 3.5.1

I'll remove the JSONTAG stuff tonight and try again. That said, the "json" tag does seem to get picked up, because I'm also using it to fix case (ie: json: someField, swapping to camelCase, which is more Javascript-y).

From what I can tell, the library just seems to ignore the "-" option. I'll try it again tonight.

@awalterschulze
Copy link
Member

Looking forward to your feedback. I just want to eliminate some variables, before trying to load everything in my head.

@svperfecta
Copy link
Author

Actually to clarify, I'm trying to get the Capacity field to not appear when marshaled to JSON at all. We use GOGO to generate models that we use internally between services, and externally when serialized to JSON by our gateway. Externally, some fields (like capacity) don't make any sense, so we don't want them to actually appear in the resulting JSON.

Perhaps what I need to do is read more on the json= field, though it is weird that that "json:" option does seem to work for changing case.

Also to clarify, I'm using this package: https://github.com/gogo/protobuf/tree/master/jsonpb

@awalterschulze
Copy link
Member

Ah ok. I don't think the jsonpb package is made to not marshal fields, except maybe omitempty.
Maybe implementing JSONPBMarshaler would be the easier way to not marshal some fields?

@svperfecta
Copy link
Author

Hrm, ok. Yep, that's going to be a little gnarly. Before I do this (and I'll happily share the code) is there a good way to do this besides rewriting marshalObject?

https://github.com/gogo/protobuf/blob/master/jsonpb/jsonpb.go#L151

@awalterschulze
Copy link
Member

So sorry, I did not initially understand that you were not looking for the semantics of omitempty, but rather the sematics of - in the encoding/json package.
The reason being that I don't think that I have ever used - in the encoding/json package.

So I still think implementing the JSONPBMarshaler marshaler is your best bet, but I agree its not ideal, given that the methods you want to call back into like marshalObject are all private.

I guess another way is to give your field a name with a prefix XXX_
https://github.com/gogo/protobuf/blob/master/jsonpb/jsonpb.go#L251
Since this will also be ignored.

If you also don't want to protoMarshal the field then there is another option using gogoproto. typedecl = false. This way the message won't be generated and then you can type it out yourself and add extra fields without a proto tag.

Another way is to use int32 capacity = 13 [(gogoproto.jsontag) = "-"]; and encode using the encoding/json package and not the jsonpb package, but you are probably after the jsonpb semantics, if you are using the jsonpb package.

All 4 of these solutions are not ideal and pretty advanced. I personally don't think its a good fit, but maybe one of these will work for you.

@svperfecta
Copy link
Author

Thanks! Yeah I still haven't figured out a plan. The custom marshaller seems like the only option. We like the jsonpb package for its ability to deal with enums and we use these fields internally with gRPC. The XXX hack is interesting, but it's a bummer to name a field this way.

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