I am writing a Go library that will decode JSON into a struct. The JSON has a fairly simple common schema, but I want consumers of this library to be able to decode additional fields into their own structs that embed the common struct, avoiding the need to use maps. Ideally, I'd like to decode the JSON only once.
Currently it looks something like this. (Error handling removed for brevity.)
The JSON:
{ "CommonField": "foo",
"Url": "http://example.com",
"Name": "Wolf" }
The library code:
// The base JSON request.
type BaseRequest struct {
CommonField string
}
type AllocateFn func() interface{}
type HandlerFn func(interface{})
type Service struct {
allocator AllocateFn
handler HandlerFn
}
func (Service *s) someHandler(data []byte) {
v := s.allocator()
json.Unmarshal(data, &v)
s.handler(v)
}
The app code:
// The extended JSON request
type MyRequest struct {
BaseRequest
Url string
Name string
}
func allocator() interface{} {
return &MyRequest{}
}
func handler(v interface{}) {
fmt.Printf("%+v
", v);
}
func main() {
s := &Service{allocator, handler}
// Run s, eventually s.someHandler() is called
}
The thing I don't like about this setup is the allocator
function. All implementations are simply going to return a new BaseRequest
"sub-type". In a more dynamic language I would pass the type of MyRequest
in instead, and instantiate inside the library. Do I have a similar option in Go?