-
Notifications
You must be signed in to change notification settings - Fork 18k
encoding/json: marshaling should have an option to lowercase field names #41448
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
Comments
Before I reply, I'd suggest that you try to not write issues in frustration. As a maintainer, they are not only harder to read, but also make me less likely to take the time to understand your issue and write a proper reply. We have a code of conduct precisely so that we can all communicate while being respectful to others :)
If you absolutely can't deal with maintaining two names for each field, the answer is usually generating code. For example, Protobuf generates Go code which produces the corresponding field tags for json. If you just need JSON support, you could do that with something much lighter than Protobuf, like https://medium.com/@aniketawati_75058/go-generate-to-automate-json-tag-generation-for-go-structs-2f83bca1f12c. Code generation is likely a good idea for a large set of people with hundreds of API structs, anyway. That is going to enable you to implement many other features which could otherwise require copying boilerplate and maintaining duplicates. |
As for the feature request in particular: adding an option just to lowercase field names is far too narrow. What if someone wants to convert |
That totally makes sense, I agree, I did use frustrated wording and that totally does not help.
Did try it out as well before I wrote this. It still does not solve the problem. For example, if you already have annotation it will not change it - which means if you are changing field name and you want to regenerate the field it will not do. And you still have to generate it eachtime and teach people to do it and expect them to do it, or run it automatically on checkin gate which is complicating the system. It is just a patch.
I totally agree. My proposal is adding Also, if passing it with each Marshal / MarshalIdent complicates function signature (you need both of these with and without func param), it might be a good idea to be able to create some struct that has a field with this key-mapping value (or nil if no mapping is to be done), and to call Marshal / MarshalIdent on that one with the similar signature as now. |
The
I'm not sure I follow. If you have a piece of Go code that generates all of your types, you can make it do whatever you want, including arbitrary field tags. You would not edit or maintain the types directly, instead modifying the generator or its input. This is similar to how Protobuf works.
I'm sorry but I strongly disagree. Go is a simple language on purpose. If you want high-level control over your types or code, code generation is the usual answer, and it's also a first-class citizen thanks to
You can't change existing behavior, because that would break existing programs. This includes suddenly treating some fields as special. Really, the only backwards-compatible option you have in Still, beware that the bar for such new options is very high, and |
Also, if you do want to suggest API changes to |
I understand all of your comments about stability, that's why I mentioned the signatures. Maybe I haven't elaborated, but the basic idea was to:
About code generation, this one did not work because of mentioned issues https://medium.com/@aniketawati_75058/go-generate-to-automate-json-tag-generation-for-go-structs-2f83bca1f12c. I accept I never built my own code generator and I do understand that it is the only way to have a glimpse of generics before generics. If I hit some performance issues with double reflection solution (as it works well enough for now) I will try to go down the code generation route, but I think my point stands: I don't think we hit some rare or obscure issue here - I think almost everyone building big APIs have this same issue. I think golang is the best program for web servers, and that many of those web servers communicate with other moving parts in JSON, and have the same issue as we do. I think that standard library should provide solution for such a standard problem. |
I have the same concern when I first use the built-in |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Duplicate of #23027 |
FWIW, this extremely popular yaml package does exactly what is being requested here by default: https://pkg.go.dev/gopkg.in/yaml.v3. It makes sense not to fight the json and yaml case conventions. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Created a struct (without json annotations) and marshaled it.
What did you expect to see?
I needed field names with lowerCammelCase.
What did you see instead?
I got them with UpperCammelCase.
Extra
To explain a bit more: go JSON decisions create a huge problem in usability that is very simple to solve.
Go forces developers to write capitalized field names if they are to be marshaled into JSON (as they are public fields).
Go never give you the option to choose field names format when marshaling JSON, except via annotations.
Annotations are terrible and are not an option at all. If I am to write JSON annotation for each field that field is called exactly the same but in other format, that's usability hell. Also, when I rename the field, I should rename annotation as well? I should teach all employees that they have to keep the annotations correct? And consider all of this on a huge API project which has hundreds of structs. That's against the very things go is about, which is simplicity and readability of code.
Because of iteroperation with other code, sometimes structs field names need to be formatted into other formats, and that's not up for a discussion. So we have to jump through hoops to get it to work. First, after JSON generation we used a regex to change each JSON key into desired format. Later, we figured out that is not working for maps (where we don't want to change the keys), so we're doing some reflection preprocessing before JSON marshaling. So yeah, now we're doing reflection twice just to marshal JSON...
I am aware that this discussion already existed. I just can't believe that the decision is still to prevent such a basic feature, so I have to reopen it.
The text was updated successfully, but these errors were encountered: