Have you ever wondered how much golang allows you to customize Json operations?
I searched about it and I found that we can declare our methods for json marshal/unmarshal operations. I can't guarantee this information is usable but I think it is nice to know. If you want to know how to do it please keep reading :)
I will give direct code examples in here so firstly there is our code:
Scenario: We have an
exampleStruct definition at line:33. This is our user model and it's contain some problematic information in it (Like credit card info). So we want to filter them in json marshal/unmarshal.
I created a type called
emailCover at line:51. I need this layer because I don't want to create recursive marshaling loop in my method by using
json.Marshal(). You don't need to do it but I think it is more safe for avoiding stack overflow.
We implemented an
UnmarshalJSON method to our cover at line:53. It basically just unmarshall all data and gives us necessary fields.
Important: Don't forget declare object as pointer in method definition.
We implemented an
MarshalJSON method to our cover at line:64. It basically just get default version of object and just sets necessary fields. And returns
json.Marshal() again. Did you notice? We put
exampleStruct insde return marshal. If you try to give
emailCover you cause a recursion. And this causes an stack overflow error.
Important: Don't forget declare object as value in method definition.
Marshal traverses the value v recursively. If an encountered value implements the Marshaler interface and is not a nil pointer, Marshal calls its MarshalJSON method to produce JSON. If no MarshalJSON method is present but the value implements encoding.TextMarshaler instead, Marshal calls its MarshalText method and encodes the result as a JSON string. The nil pointer exception is not strictly necessary but mimics a similar, necessary exception in the behavior of UnmarshalJSON.
So this methods called in inheritor objects also.
encoding/json document: https://pkg.go.dev/encoding/json