I have had this article in my head for almost a year but reading Practical API design book have forced me to finally write it. The idea is not new or revolutionary, on the contrary it’s quite obvious: There are different programming worlds. We can use metaphor of workshops.
Jaroslav Tulach, author of Practical API design book works in one workshop. He is creating components for other programmers. Lets imagine that he is making nuts and bolts. Of course, his nuts and bolts are more sophisticated, but for sake of argument lets imagine this simple nuts and bolts scenario.
Apparently, his customers are other craftsman and their main requirement is compatibility. They want to use his parts in existing machines, they want to use the same tools they currently have. He just can’t decide, that hexagonal head is not modern any more. All his customers have tools for them. Therefore, he has too maintain compatibility. Of course, in some cases he can enhance quality by using better materials, he can introduce better types of components, but once a component is sold to a customer he can’t change its dimensions or other important properties. For him backward compatibility and well defined API are crucial. I think that definition for API should be: “Something that is not allowed to change”.
I am on the other hand server-side Java programmer. I write software mainly for end-users. Lets say that I am building custom-made bicycles. You know, some people have so special requirements that they can’t go to a shop and just buy a bike. They need special, super-duper tailor made bike.
Usually they do not care what parts I use. They want me to meet their requirements and do it as fast as possible. In this case, I don’t care about API at all. I just take existing components and put them together. Of course, I want this components to be well supported, developed in backward compatible way. But me personally, I do not care about creating APIs. I am just using them. Sure, I create my own components, but I do it only because I have to. Sometimes I have to connect two incompatible parts, sometimes there is no-one who makes the part I need. But I always prefer to use already existing parts. I do not know how in bike workshop, but in software there usually is no need to write your own library or new API. Of course, sometimes you are doing something really revolutionary, sometimes your customer requirements are really special, but in my experience, usually customers want something that has already been done hundred times before and there is already someone who makes corresponding parts.
There are only two cases when we have to define an API. The first one is, when we want to reuse custom made components in different projects. It looks like a plausible argument, but I think that in 99% of cases there already is an existing library that already does almost exactly what you need. And I think it is always better to use existing solution then reinvent a wheel.
The other situation where you have to define an API is when you interface with other supplier. For example if your customer wants to mount a rocket launcher on the bike. Then you usually have to agree on some interface between you and the rocket launcher manufacturer. I would bet that there is already a standard for this, but if there is no standard you have to define an API. In my workshop it is usually done using WebServices or other XML based format just because it is easier to change such API in almost compatible way. I usually do not use Java based API just because all the versioning and other issues it brings.
Well, it looks like I do not do anything useful. Hell, I have to defend myself. My added value is that I put those parts together. Customers do not pay me for making bicycle components they pay me for delivering a tandem-tricycles for elephants. That’s my job. To build such thing as fast as possible and as cheep as possible. They do not want me to loose their money by reinventing a wheel.
So in my case creating an API is not useful. Sometimes it is even harmful. I’d like to be flexible, I want to be able to fix my mistakes as fast as possible, I’d like to change my design quite often, I do not want to maintain backward compatibility. I do not have to. The only people who will be influenced by my changes are my colleagues. It is quite easy to fix their components accordingly to my changes. At least in software world.
Of course that I try to create well encapsulated and reusable classes. Of course I try to create some kind of communication interface to all my modules. Even for internal usage, I like to have some level of cluelessness. But I would not call it API. It is something one level under API. For me it is just an implementation trick I use to make my life easier. I am not publishing it outside the team, I know that it is not stable at all. It’s not an API it’s just PI. Of course the distinction is not clear, but I still feel that there is a difference between a stable API and volatile internal PI. Both of them hide implementation details but only API has to be stable.
There are other types of workshops as well. There are for example mass producers. They sell bikes or software in boxes. These people live somewhere in between. They try to use existing parts as much as possible, but they have to differ somehow from their competitors. So they have to provide something special. In this case, there might be a reason to create a special component and make it standard, so they can share this component between teems working on different products. But again, I do not think that they need stable well defined API so much.
There are of course other types of workshops, but my metaphor is slowly reaching its limits so I will abandon it. What I want to say is, that there is no one size fits all approach or advice. What a surprise!
For example, you can read that you should not optimize your code because JVM will do it for you. That’s true unless you work for mobile devices. I recommend you to read this, it goes against everything I believe in, yet in their use case it’s valid.
There are other examples, I am sure you will come up with your own. The important thing to realize is that there are different worlds for which different approaches apply. So if you do not agree with someone, maybe the reason is that he is from completely different world.
This is pretty useful blogpost. Something, almost everybody knows, but lots of us don’t know, that we know it. In other words: a trivial idea with great importance.
Your metaphor seems to be very handy are we allowed to spread it? 😉
I’m glad you like the post. Use it as you want.
I think this part is important:
“I’d like to be flexible, I want to be able to fix my mistakes as fast as possible, I’d like to change my design quite often, I do not want to maintain backward compatibility. I do not have to.”
Every programmer wants that. Me too – it means that you have complete freedom while extending or updating your existing code. And everyone wants to be free. I guess Jarda Tulach too.
But there you go. Sometimes there comes time, when other programmers start suffering from your freedom. They start to complain that you force them to adapt and repair their code again and again. And that’s a signal, that you are no more doing PI but an API.
It reminds me Czech saying: the freedom of one ends there, where the freedom of another starts. And API is just representation of such border between freedoms.
This situation can happen to anybody – even you. Never say never.
So enjoy your freedom, it will last till somebody starts to beat you in the head. 🙂
Sure, I totally agree with you. The important thing to notice is that rules for writing public APIs and inhouse APIs are different. When you are coding internal API, you just write a code you need. Well, sometimes you try to make it more general and reusable, you try to create a generic library.
But even in this case you can simply check how your colleagues are using the API and do your changes accordingly. That’s the main difference between inhouse APi and public API. In public API you have no idea how it is used so you have to be much more defensive.
Interesting point of view on this subject has been published recently.
Yes, in that case – I have experience only with inhouse APIs, but even then I have run at the problem of backward compatibility. And 10 dependent people have enough power to make me think about it. But of course this is nothing comparing with APIs open to wide public.
Regarding the InfoQ post I must say that reusable libraries and modules in our area is crucial. Coding everything from scratch got us into the position where we just started to be less competitive to our rivals. Even when making highly customized software according to customer requirements reusing things that could be reused is very important for keeping costs at the level customer is willing to pay.
That’s my experience.
The approach that an ‘ordinary developer’ does not need to write a good API or maintain compatibility is a very common and repeated mistake.
It’s OK for a one-man-show project, or for a project developed by a compact team, where all members meet in a kitchen every day. In such small teams, synchronization between developers is almost instant, as all people share the same common knowledge about all code/product features.
As the development team starts to grow, team splits up into several ones – they may be all developer teams, some of them may be on-site customer support teams. It’s even worse if business partners start to integrate with the product – another teams crawl in.
Another axis are bugfix releases developed in parallel with the mainline or some customized forks; with continuously changing core, such parallel development is very hard, and it is yet harder to integrate the parallel branches back into the main product line to exploit the synergies.
Here starts the need for maintaining API, changelogs for releases, migration guides, compatibility, etc. Developers in these teams primarily communicate within the team – and sync between all parties becomes more and more inappropriate and time consuming. The more the individual team’s schedule, task flow, or management is separated, the more the bulletproof API interfaces are needed.
So a short summary: If you are alone on a project, or a very small and compact team, don’t bother with APIs. If you are suffering high fluctuation, or your team is larger, separated into groups, different product lines, etc, DO invest into building a solid API-level interfaces. The costs will repay back soon.
I agree with Svata. BTW to be quick is not an excuse, sometimes you have to be slow in the beginning to be much much faster at the end. I think that everything is in separation. The more you can do it the more happy you are later. You can bend this rule for sake of speed, but don’t complain later 😉 Of course choosing the right balance between an effort and later income from it is always challange 😉 I haven’t read the book yet but may be it’s more about principles (as such are always hard to follow 100% in real life) But it’s good to know them. (Not all my bash scripts are thread safe :))