go / intermediate
Snippet
Implementing Custom JSON Marshaling for Domain Types
By implementing json.Marshaler and json.Unmarshaler on custom types, you control how Go structs convert to and from JSON. This is particularly useful for representing enums as readable strings in JSON API payloads rather than raw integer values.
snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package mainimport ("encoding/json""fmt""strings")type Status intconst (Pending Status = iotaActive)func (s Status) MarshalJSON() ([]byte, error) {var str stringswitch s {case Pending:str = "pending"case Active:str = "active"default:str = "unknown"}return json.Marshal(str)}func (s *Status) UnmarshalJSON(data []byte) error {var str stringif err := json.Unmarshal(data, &str); err != nil {return err}caseInsensitive := strings.ToLower(str)switch caseInsensitive {case "pending":*s = Pendingcase "active":*s = Activedefault:return fmt.Errorf("invalid status: %s", str)}return nil}
Breakdown
1
func (s Status) MarshalJSON() ([]byte, error) {
Implements the json.Marshaler interface to convert the custom integer status type into a human-readable JSON string.
2
func (s *Status) UnmarshalJSON(data []byte) error {
Implements the json.Unmarshaler interface. It uses a pointer receiver to modify the target value during JSON decoding.
3
*s = Pending
Dereferences the receiver pointer to update the status based on the parsed JSON string value.