-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: encoding/json: preserve unknown fields #22533
Comments
Stepping back a moment. What is the use case you have in mind? Proposals are far more effective if they start with concrete problems they are trying to solve. |
Hi! As for the first bullet point it is already described in the proposal (last paragraph: key collisions). Regarding Use case is also somewhat described in the proposal: decoding into a struct, editing, and then encoding back while preserving fields. It is a relatively common need in distributed systems where JSON is used for RPC. For context it can be interesting to read this issue protocolbuffers/protobuf#272 about protobuf removing support for preserving unknown fields and then adding it back. |
I'd like to save this issue for a future rethink of all of encoding/json. It's important we don't keep adding piecemeal each new feature that seems useful by itself. |
It is quite common for JSON APIs and formats to mix defined and custom keys within a single object e.g. JWT claims. Having a placeholder for unmapped fields per struct would allow for loose structure parsing. What is the status on the rethinking? I'm offering an implementation to your likings, if there's any sympathy for the concept? |
I'm late to the party, but isn't this proposal very close to #6213? |
In #42417 I proposed to have the following syntax:
So And for the question what to do about overlapping fields, we could have that specified with a flag, like:
To have extra fields override any struct fields. |
I agree with @mvdan that if this feature is provided, it should probably be implemented in terms of a more general feature (i.e., #6213) that permits splitting off part of a JSON object for a Go struct into some other data structure. Assuming that #6213 exists, it may be conceivable that
Alternatively, if the feature provided by #6213 is sufficiently simple, we provide no helper types and leave it to the user to figure out how to preserve unknown fields. Also, we need to consider how such a feature may interact with the |
Raw implies unmodified, so we can't collect fields in raw. The main reason for parsing extended fields together with an expected structure is performance. Using raw per field causes the opposite effect (with multiple parse operations). Options relying on field order should be avoided. The specifications prohibit such logic explicitly. |
Hi all, we kicked off a discussion for a possible "encoding/json/v2" package that addresses the spirit of this proposal. |
Yesterday I've implemented #15314, which allows to optionally fail JSON decoding if an object has a key which cannot be mapped to a field in the destination struct.
In the discussion of that proposal, a few people floated the idea of having a mechanism to collect such keys/values instead of silently ignoring them or failing to parse.
The main use case I can think of is allowing for JSON to be decoded into structs, modified, and serialized back while preserving unknown keys (modulo the order in which they appeared, and potentially "duplicate" keys that are dropped due to uppercase/lowercase collisions, etc.). This behavior is supported by many languages / libraries and other serialization systems such as protocol buffers.
I propose to add this type to the JSON package:
Users of the JSON package can then embed this type in structs for which they'd like to use the feature:
On decoding, any object key/value which cannot be mapped to a field in the destination struct would be decoded and stored in UnknownFields. On encoding, any key present UnknownFields would be added to the serialized object.
I can think of a couple edge cases which are tricky, and I propose to resolve them as follows:
Nested structs
It's possible for nested structs to also declare UnknownFields. In such cases any UnknownFields in nested structs should be ignored, both when decoding and encoding. Pros: it is consistent with how we already flatten fields, and it's the only way to ensure decoding is unambiguous. Cons: keys that somehow were set to UnknownFields in a child struct would be ignored on encoding.
Key collisions
When encoding it's possible that a key in UnknownFields would collide with another field on the struct. In such cases the key in UnknownFields should be ignored. Pros: it is consistent with the behavior in absence of UnknownFields, seems generally less error prone, it cannot happen in a plain decode/edit/encode cycle, it's unambiguous. Cons: it can possibly lead to silently dropping some values.
PS: I'm happy to do the implementation should the proposal or some variation of it be approved.
The text was updated successfully, but these errors were encountered: