Introduction
In the first part of this series I introduced the concept of Developer Experience and why I think it is important that we start investing more into improving the Developer Experience. In this part I will lay down some foundations on how this could be done.
The pillars of DX
Know your user (i.e. the developer)
Not all developers are alike. You can see this within a company like Oracle: developers in the DataBase group are different from developers in the Middleware group, who in turn are different from developers in Application Development. They have different skills, write in different programming languages and use different tools. Even within groups there are differences. e.g. between CRM and HCM, and even between product teams in the same group (e.g. Human Resource and Payroll). Developers use different lingo to verbalize their domain, build their own tools, etc.
It is imperative that you get to know how a developer goes about their day, not only what tools they use but also how they use them.
Simplify All the Things
When a device as simple as a door has to come with an instruction manual – even a one-word manual – then it is a failure, poorly designed.
– Donald Norman, The Design of Everyday Things
The tools and APIs we create for developers need to be designed to be intuitive to use:
- Use affordances to guide the developer: clearly name the API, the parameters it needs and what it returns. If errors are raised, make them understandable and actionable, explain how the developer can fix or avoid the error.
- Try to “design away” common problems rather than documenting workarounds. The more work you put into the design of the API and tools, the less support you need afterwards.
It’s worth pointing out again that designing for simplicity is not easy, “simple” != “easy”; it is very simple to stop smoking, but it surely is not easy.
Simplicity does not negate the need for supporting documentation, forums, examples, etc. These tools need to cater to beginners and experts alike. Novices need to be able to get started quickly but experiences users need deeper knowledge as their requirements get more sophisticated. This can be done by establishing conventions that can be overridden with configuration options (convention over configuration), essentially you default as much as possible for the new user. Experienced users can then override these defaults.
Simplicity is hard work. But, there’s a huge payoff. The person who has a genuinely simpler system is going to be able to affect the greatest change with the least work. He’s going to kick your ass. He’s gonna spend more time simplifying things up front and in the long haul he’s gonna wipe the plate with you because he’ll have that ability to change things when you’re struggling to push elephants around.
– Rich Hickey, Creator of the Clojure programming language
These concepts are pretty much identical to UX pillars, remember, UX ~= DX!
Practical DX
Create Different Developer Personae
Find out who will be using your Tools and APIs (for the rest of this article, APIs are considered “tools”) and create personae to represent those users. Then build your Tools for those personae, not some imaginary “average” developer. Also understand your users’ users, i.e. who are these developers building applications for. E.g. if you APIs are being used in off-line applications, you might not have to focus so much on performance, maybe the end users are more interested in precision instead (think financial applications). Having an understand of all these factors will improve you API design.
It is equally important to understand what devices they are writing applications for. APIs for Mobile Applications might be simpler than those for Desktop applications, wearables could be even simpler.
Practice Developer Relationship Management (DRM)
Have a team of Developers (not marketing people) work with the external developer community. Have them evangelize the Tools to developers, provide support where needed and feed input from this community back to development to improve the Tools. Target prized partners individually and the broader community through speaking engagements, sponsorships, hackathons, social channels, etc.
Form partnerships with developers that build cool applications with your Tools. Let them showcase their work in an on-line gallery (“Apps build with CRM APIs!”), provide loaner devices if needed, hand out free development accounts, etc.
Drink Your Own Champagne
The only way to ensure that your Tools are meeting DX standards is by using them yourself in development. You have to put yourself in the shoes of your potential users in order to see where things can be improved. This is a way of battle testing your Tools before you release them to the public.
Create a Layered Architecture
Cater to the novices with high level Tools that default what they do not need to know and let experienced developers modify and configure those Tools as they see fit. We have to ensure that any developer can build an application with our Tools. When you take an iPad out of its box, you don’t have to assemble it first and then read the QuickStart Guide while you charge the battery, you take it out and switch it on. Our Tools should work the same.
Measure
We have to measure Tools usage, not (just) for billing purpose, but to gauge their usability. This will allow us to scientifically deprecate and cull certain Tools and improve other ones. Without measuring you cannot know if your API Strategy is even working or improving over time. This should be build into the platform from the get-go.
Flatten the Learning Curve
Create Idiomatic APIs by follow the conventions of the languages and frameworks your API is designed in. If you have a Web Service, this means following the conventions of HTTP and REST. If you have libraries in various languages, avoid the temptation to auto-generate them all from a common base. Instead, have their interfaces designed and battle-tested by people familiar with the language. Make sure they fit culturally.
Build plug-ins for popular development tools that developers are using, e.g. Yeoman, Grunt, Gulp, Bower, Sublime Text … Don’t force them to use your tools.
Provide a Support Ecosystem, this should include On-line Documentation, Recipes, How-to’s and tutorials. We also need to provide an On-line Playground that will allow potential developers to start using our Tools without even downloading anything.
Also, make your APIs Backwards compatible. If you cannot, version your APIs and encourage upgrading while you keep supporting the older versions.
Finally, make error messages understandable, useful and actionable. Nothing is more infuriating for a developer than displaying a useless error message.
Great posts.
As an example of how *not* to design an API for good DX, take a look at the JIRA REST API;
https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-create-issue
When you’re trying to create an issue via the API, you have to send data in a bunch of different formats depending on what type of widget the user of the JIRA web-ui might use to enter it. The parameter to set a field might be;
– Plain text, just a JSON string literal
– A JSON object containing the field value in the “key” attribute
– …or with the value in the “value” attributue
– …or the “name” attribute
– …or the “id” attribute
– A JSON array, with a list of objects in one of those formats
And date fields are in a different format depending on if they’re date or datetime.
And numbers won’t be accepted if you pass them as strings.
And then there’s “special” fields, like timetracking, that appear completely differently in the API to how the user enters them in the UI, and have to be sent in a semi-secret format that’s not described in the field meta-data.
Here’s a crazy idea JIRA; how about I just send you a string and *you* work out whether you can treat it as a string, or whether you need to wrap it into the id/name/value/key attribute of an object. If I send you a string, and you want a number; try parsing it yourself? If I send you a date and you want a datetime; default the time in as midnight, maybe. If I send you a datetime and you only want a date; ignore the time component. If you want an array and I only send a string; treat it as an array with one element. If you only want one element and I send you an array; just pick the first value you find?
Bad DX does not a happy developer make!