As explained in the thread, that is because Go best practice is to treat `nil` and `[]T{}` as the same thing in every API. If you want an explicit `null` in your JSON you can use `*[]T` as your field type, and then it makes more sense.
The very idea of allowing the nil value for slices seems to be very strange and inconsistent, as slices are struct types, not pointer types in Go (they contain a pointer and other members). Just one of the many ways that builtin types in Go are fundamentally different from user-creatable types, I guess...
It is admittedly very weird that Go supports nil slices/maps instead of just having the nil value be an empty slice/map that points to constant storage. But as long as Go has a semantic difference internally, representing that as null externally makes sense. Though I suppose as long as the conversion from null to empty array/object is opt-in it's fine.
For context, we recently had a bug where backend forgot to initialize their map, so they were sending us a null where we expected an object, and it would have gone undetected for much longer if the JSON didn't contain a literal null there.
The nil value for a slice is an empty slice that points to constant storage: Data=0, Len=0, Cap=0. That's just not the same as Data=somethingelse, ... which you get if you allocate something.
(And all Go zero values are exactly what you get with the relevant RAM filled with the zero byte.)
The very idea of allowing the nil value for slices seems to be very strange and inconsistent, as slices are struct types, not pointer types in Go (they contain a pointer and other members). Just one of the many ways that builtin types in Go are fundamentally different from user-creatable types, I guess...