Thoughts on Code Style in Library Design
Designing the API for an XMPP client
I have been recently working on our Fluux XMPP library, a library that can be used to implement clients and server components in Go.
XMPP protocol is flexible and contains many extensions. It can be daunting to get into XMPP so it’s very tempting to add new tools to make it more convenient for newcomers to get into the protocol.
The challenge is about striking a right balance between keeping it close to the XML stream traffic, simple and powerful but easier to document and more welcoming for newcomers.
I have made some experiments recently that have sorted the developers into two groups, apparently depending on their taste.
The current way to write an XMPP disco IQ response is as follows:
iqResp := xmpp.NewIQ(xmpp.Attrs{Type: "result", To: "service.localhost", Id: iq.Id, Lang: "fr"})
identity := xmpp.Identity{
Name: "Test Component",
Category: "gateway",
Type: "service",
}
payload := xmpp.DiscoInfo{
XMLName: xml.Name{
Space: xmpp.NSDiscoInfo,
Local: "query",
},
Identity: identity,
Features: []xmpp.Feature{
{Var: xmpp.NSDiscoInfo},
{Var: xmpp.NSDiscoItems},
{Var: "jabber:iq:version"},
{Var: "urn:xmpp:delegation:1"},
},
}
iqResp.Payload = &payload
It is very close to the hierarchical nature of the XML structure.
My experiment leads to the following code:
b := stanza.NewBuilder().Lang("fr") // Create builder and set default language
iq := b.IQ(stanza.Attrs{Type: "result", To: "service.localhost", Id: "disco-get-1"})
identity := b.Identity("Test Component", "gateway", "service")
iq.payload := b.DiscoInfo().
SetFeatures(stanza.NSDiscoInfo, stanza.NSDiscoItems, "jabber:iq:version", "urn:xmpp:delegation:1").
SetIdentities(identity)
Some developers feel more comfortable with the first approach. Other feels more comfortable with the second one.
The second approach can still generate the first structure, so could please both types of developers. You can read the discussion on Github.
Still, designing an API is always a challenge. You have to spend a lot of effort to make it right, striking the right balance between its capabilities, yet trying to guide the developers as much as possible to help them write good and correct code. You need to make choices about which code styles you would like to promote. And most of all, you need to take the time to discuss, to be aware of difference in code-style preferences.
And you? What is your preferred coding style?