-
Notifications
You must be signed in to change notification settings - Fork 328
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
Use EmitDefaults: true for jsonpb.Marshaler in generated server code. #103
Comments
Right, this comes up pretty often as a stumbling block for our users. As you note, it's explicitly supported, too. I wonder whether this would break behavior for anyone, though. We should probably be cautious and treat it as a change we can only make with a major version bump. |
@spenczar If you want to slot this into the v6 release I'll happily provide a pull request with the code fix and documentation. |
any chance this will make it into v6? |
Some context and comments on this issue. Zero and Undefined are not the sameIn many languages (specially in JavaScript) The network protocol doesn't differentiate between zero-values and undefined, with the goal of using as little bandwidth as possible. Autogenerated clients de-serialize using the official json-pb mapping protocol: https://developers.google.com/protocol-buffers/docs/proto3#json. If your service actually needs to differentiate between zero and undefined values, you should add a second boolean property in the Proto file (true if the value exists), or wrap the value with one of the well known message types (message values can be undefined). Manually handling/debugging JSON requestsIf you are using curl (or similar) to debug your Twirp service, you probably find annoying having to guess if the missing fields are zero-values, undefined or actually missing values. I hear you, this may be a real issue. Is EmitDefaults a good idea?Yes I think it is. Looking back, I personally think Twirp should always have use Skipping zero values in the serialized JSON may save some bandwidth, but if you need performance you would use Protobuf instead. The JSON serialization should help with debugging and convenience. Is EmitDefaults backwards compatible?Changing the protocol to make Another option is to allow using a flag like |
I'm running into this as well :) I think a better option than having emit_json_defaults as a param, is to give users a hook into creating the And maybe even further, to have the hook take a That said, keeping the protocol simple and less customizable is tempting from the maintainer's perspective. On the other hand, this would unblock a lot of users. A compromise would be the protocol would only guarantee the default behavior and if a user wanted to pass a custom marshaler, it's their responsibility to ensure all of their clients are compatible. |
is there something new in this? |
I agree with Mario's opinion above that However, this behavior will not change because it has significant potential to negatively impact Twirp's users. For instance, services using JSON in production would be impacted. A service that starts including default values in its JSON responses may experience a significant increase in the size of its response payloads, which may lead to unexpected changes in performance. Including this in a new major version was mentioned above, but this issue doesn't seem to outweigh the organizational cost that would be required by Twirp's users to safely perform a major version upgrade. I agree that Twirp could make it possible for users change the behavior of the |
Fixed in PR #271 JSON serialization using |
protoc-gen-twirp/generator.go#L1012
In generateServerJSONMethod the jsonpb.Marshaler instance should likely include
EmitDefaults: true
as an option. While Go has a concept of zero values, javascript does not (i.e. the number0
andundefined
are very different things).Let's say a proto Message struct in Go is:
Serializing this Hat instance with the twirp jsonpb.Marshaler does the following:
JSON:
Thoughts?
The text was updated successfully, but these errors were encountered: