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?


Let us know what you think 💬


Leave a Comment


This site uses Akismet to reduce spam. Learn how your comment data is processed.