2

I am currently reading Clean Code by Robert C. Martin and in Chapter 8: Boundaries one can find this paragraph:

We wanted to tell the transmitter something like this:

Key the transmitter on the provided frequency and emit an analog representation of the data coming from this stream

We had no Idea how that would be done [...] we defined our own interface [...] this was the interface we wished we had.

Now I am wondering if one should use this kind of pattern, which appears to be an Adapter, with every Api call I am using. It seems intuitive if I already have the code surrounding the Interface which is how he describes it but if I start out with the data from the API or only do little transformation to the data, it seems to be easier to work with the dataformat, that is given to me.

Or is this a case of me overthinking it and should this (like most things) be used sometimes íf it helps and if so when might this be? In the same situation that he described? Are there more?

2
  • Here's a different way to look at it; people often initially adopt the format of the JSON response from an API and build their application around that. Now, depending on what you're doing, the data might just "pass through", or you could have all kinds of things depending on that exact format - from business logic to various UI pages/views. Now, keep in mind that a lot of those views & logic won't depend on the entire API, but parts of it. Then the API changes (maybe it's in an early phase), and the changes might not be of a fundamental nature, but the knee jerk reaction is often... 1/2 Mar 4 at 18:43
  • 1
    ...to basically reimplement everything, to keep the internal data format in perfect sync with the API for some reason, instead of just converting the data to the old format (which now plays the role of an adapter interface) at component boundaries, + a few changes here and there for aspects that are truly novel or important to incorporate. The application worked fine before! So, you can start with an existing interface (you don't have to invent it); it's just that you have to decide what to do when circumstances change. 2/2 Mar 4 at 18:43

2 Answers 2

4

Robert Martin's advice is caustic and extreme; perhaps he thinks this is necessary to get the point across. (To those who want to dispute this, he is on record saying that if you make a mistake that costs your employer money,you should writ them a cheque for the amount.)

So when should or shouldn't you create an adapter for using a foreign API? There are basically two reasons why you should do it: code coherence and resilience in the face of change.

Change is the great enemy of comfortable programming. As soon as you've adapted your code base perfectly to the requirements of the environment, the environment will change. A good code base is one that requires only a little work when this happens. Now, if you use a foreign API, the details of using that API will probably change when you want to use cool new features, or upgrade to avoid vulnerabilities, or to achieve parity with your competitor, or many other reasons. If you've created an adapter that encapsulates the foreign code, you'll change the adapter and that's it, no matter how much use you make of the API. If you haven't, then you have to change as many places as there are calls to the API. This is more work --> bad.

But coherence is possibly even more important. Even if you only use that API once and will continue to do so, it is better not to mix concerns e.g. of marshalling arguments, waiting for the result asynchronously, mapping foreign data types etc. with the code that implements your own business logic. This allows you to keep the thinking about this API in one little module and never think about it at all otherwise. And this is an advantage that you get from the first occurrence on.

4
  • Do you think this way: "Robert Martin's advice is caustic and extreme;" in general or are you applying it to my previous quote only? If in general may I ask why?
    – SirHawrk
    Mar 4 at 14:16
  • 1
    It's a general thing. Martin thinks (or claims to think) that no method parameter may be boolean, in fact all method parameters must be interfaces. He thinks you should consistently work at least 60 hours a week (1/3 on self-improvement, for no pay). He writes that you should test your own code as much as humanly possible, rather then running even the slightest risk that a defect might slip through to be caught by the QA team. All these aren't exactly wrong, but no one will ever follow them as written, and I think you get your point across better with motivating examples than with hyperbole. Mar 4 at 14:36
  • Decent insight. I am still very new to the (developing) world (barely 20 yo) so are there other authors you think bring across similar principles in a better way?
    – SirHawrk
    Mar 4 at 14:54
  • I agree with the two reasons. YAGNI says wait until the change actually happens, because in theory anything can change and that will seem a valid justification to always use an interface. Change can be hard to predict. Plenty of experienced devs will say they built designs for change that never happened, and it was wasted work. Mar 5 at 20:28
1

Having your own interface, has multiple advantages in my eyes.

For one, it helps you to focus on your needs. This makes then the discussion with the other side easier.
Also, you do not have to use the names of the fields, how they are provided in the API. They send a "billingDate" but this is a "invoiceDate" in your app. So you just map it, and then the rest of the application can happily work in "their" language.

But my favorite is, that if the API changes, then you can decide HOW this should be reflected in your application. Eventually you just have to change some mapping, but the internal interface can stay the same. No need to change anything in the deeper core of the application.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.