I am writing a go client for the Flowdock API. Their API for Message has a number of attributes two of which are Event
and Content
When Event = message
then Content
is a string. When Event = comment
Content
is a JSON object.
I want to defer unmarhsalling Content
until it is needed. To do this I map RawContent
in my struct and define a Content()
method on Message
to return the correct object.
Here is the code to illustrate:
package main
import (
"fmt"
"encoding/json"
)
// Message represents a Flowdock chat message.
type Message struct {
Event *string `json:"event,omitempty"`
RawContent *json.RawMessage `json:"content,omitempty"`
}
func (m *Message) Content() (content interface{}) {
// when m.Event is a message the RawContent is a string
// real code handles unmarshaling other types (removed for this example)
return string(*m.RawContent)
}
func main() {
var message = &Message{}
rawJSON := `{"event": "message", "content": "Howdy-Doo @Jackie #awesome"}`
if err := json.Unmarshal([]byte(rawJSON), &message); err != nil {
panic(err.Error())
}
event := "message"
rawMessage := json.RawMessage("Howdy-Doo @Jackie #awesome")
want := &Message{
Event: &event,
RawContent: &rawMessage,
}
fmt.Println(message.Content(), want.Content())
}
The result of running this is: http://play.golang.org/p/eds_AA6Aay
"Howdy-Doo @Jackie #awesome" Howdy-Doo @Jackie #awesome
Note: message.Content() and want.Content() are different!
At first I did not expect the quotes to be included in message but it makes sense because of how the JSON is parsed. It is just a slice of the whole rawJSON
string.
So my questions are:
- Should I just strip off the quotes?
- If so what is the simplest way in Go to strip? maybe this: http://play.golang.org/p/kn8XKOqF0z lines(6, 19)?
- Is this even the right approach to handling JSON that can have different types for the same attribute?
Here is a more complete example showing how I handle a JSON RawContent
: http://play.golang.org/p/vrBJ5RYcql