This is a proposal to support a new Marshaler interface with a context.Context in encoding/json.
*Use cases:* Many REST APIs include meta-data that controls which attributes should be included and omitted in the HTTP response body. These controls can be static, meaning the serialization behavior is specified at design time and does not change at runtime. For example, some attributes may be declared as read-only, read-write, read-on-create, write-only, create-only or no-access. A write-only property would be sent by a client in the POST request, and it would not be serialized in the response. In other cases, the serialization behavior is dynamic and determined at runtime, based on some contextual information. For example, the OData $select operator is used by clients to specify which attributes should be returned in the response body, and other attributes are supposed to be omitted, which is useful for IoT and mobile applications. As another example, regulations and security policies may specify that some attributes must be masked or anonymized. The data masking and anonymization behavior may depend on the data sensitivity level, the role of the user accessing the data, and other runtime attributes. Specific examples of sensitive data are credit card numbers, IP addresses, serial numbers, and Personally-Identifiable Information. Furthermore, in a SaaS environment, the same API may be used by multiple end-users, and each end-user has the ability to assign a sensitivity level to various attributes. *Solutions with existing go runtime:* There are multiple approaches to solve these use cases. For static use cases, one approach is to create separate Go structs for each desired serialization output (HTTP request, HTTP response, data serialization to back-end services, etc). It is also possible to create multiple REST paths, each path providing different levels of access to the data, and assigning authorization rules, but this is still fairly static and must be determined at build time. For dynamic use cases, there is a combinatorial effect, so it's not practical to create separate go structs for each possible combination. Other serialization approaches include the use of reflection, manipulating JSON documents with map[string]interface{}, or creating an enhanced implementation of encoding/json that provides support for more customization. *Proposed solution:* One approach that would really help to reduce the amount of glue code is to add a context to the json.Marshaler interface: MarshalJSON(ctx context.Context) ([]byte, error) Of course, it is not possible to add the argument to the existing MarshalJSON() method, as this would break the backward compatibility promise of the json.Marshaler interface. But it is possible to create a new MarshalerWithContext interface. The interface specifies a MarshalJsonWithContext method that takes a context.Context argument. With a context.Context, custom marshalers can access the context and determine how to marshal the objects at run-time. To validate this approach, I tested a modified version of json/encode.go,. The existing MarshalJSON method is still supported and the package remains backward-compatible. When the new interface is implemented by a particular receiver, encode.go determines the receiver implements the new interface and calls it with the caller's context. I found this approach makes it possible to write much more concise and readable application code, compared to any other approach we have tried. *Next steps:* I've seen several variants of this request in forums and github. Requests have been closed because of a lack of valid use cases, backward compatibility or other issues. Is it worthwhile to proceed with a proposed contribution? Or do golang maintainers strongly believe encoding/json should not support passing a context.Context to the custom marshalers? Thank you. Sebastien -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.