0

Within an organization, suppose you have an internal tool used by different teams and for different use cases. This package offers APIs in different languages.

  • One could say that having multiple APIs enables more people to use the tool, as they don't have to learn a new language and can use their favorite one.
  • On the other hand, one could also argue that this makes code reuse more difficult. If team A uses language X and develops a nice script using the tool, team B can reuse the script only if they also work in language X.

My question is: from your experience, what is the global impact of having multiple APIs (potentially more people using the tool, but they can't share their code) or a single one (fewer people using the tool, but they can share their code)?


Example

An organization has created an internal package to get a weather forecast, with Python and C APIs.

One team working with Python creates a new component out of that, which aggregates weather forecast and also traffic (with the help of another tool) for the user's position.
While this code is useful, it has nothing to do with the weather forecast tool's API and it's not generic/bullet-proof/meaningful enough to become a separate package.

Another team working with Python could reuse this new component with some minor adjustments while the team working with C would have to rewrite the whole component from scratch.

14
  • The second argument is obviously flawed. "If team A uses language X and develops a nice function", but without "using the tool", because it does not offer an API for language X, then team B can also reuse the function only if they also work in language X. This has nothing to do with the availability of multiple APIs.
    – Doc Brown
    Nov 9, 2018 at 15:19
  • Functions that you want to reuse should be implemented in the libraries/api's, never on the implementing side.
    – fstam
    Nov 9, 2018 at 16:21
  • Is this API intended for use outside the team, e.g. for the general public? Or is this an internal API?
    – John Wu
    Nov 9, 2018 at 17:34
  • @JohnWu In this case, it would be internal only but not within a team only.
    – filaton
    Nov 11, 2018 at 6:03
  • @DocBrown Sorry, I think the term "function" here was not the most appropriate. Please see my updated answer with the example :)
    – filaton
    Nov 11, 2018 at 6:05

3 Answers 3

1

Providing multiple API's does not reduce your own projects ability to reuse its own code between those API's (when well engineered), nor does it limit the ability to share code between projects (otherwise we would have to rewrite the operating system each time we make a new program).

I'm going to rephrase your question as:

Does providing multiple API's limit my clients ability to share and reuse code?

Short answer: no.

Longer answer: Other stuff does, not the number of API's.

Reuse itself has no technical barrier that cannot be easily overcome. Particularly in this day and age.

There are many libraries out there that allow one language to call into another*. This might be done by interpreting the other program (embedded put-on, lua, tcl, etc... (even c)), or by marshalling the call across to the compiled component such as by JNI, COM, HTTP, SOAP, etc..., or even by directly/dynamically linking the component.

Even if the component does not already support it, it should be reasonably possible to provide a shell for the component which allows shell scripting (available from any desktop/server language) to work with it.

So from a user perspective, there is no technical reason why they could not share their nice script, with someone else who wishes to use it.

The main issue is in fact the issue of any public service/library maintainer. When you share code there are a number of incidental responsibilities.

  • It needs to be reliable - This code is being depended on, it must work, or reasonably fail.
  • It needs to be stable - Updates should preserve the interface behaviour. Breaking changes should be flagged, have work-arounds, and migration paths.
  • It needs to be documented - You can't use even the nicest script without knowing how.
  • It needs to be maintained - Bugs happen, Vulnerabilities are discovered, upstream systems change. These have to be solved.
  • It needs to be distributed - Code that you can't access is unusable, whether behind a service, in a binary, or as source.
  • It needs feedback loops (a community) - Code is just an artefact of a community of individuals who know the problem being solved, that is the most important thing ever. The code is just the best guess at a solution.

I would not consider making my software dependent on other software that does not have at least these incidental properties. As an API provider you are aware how non-trivial these things can be.

If your own clients ability to share code is crucial to your platform/application. Consider offering GitHub like services, or some form of package manager. This would reduce the burden of these incidentals on the downstream developers, while also reducing the burden on their clients. It would additionally improve the sense of community around your own software, bringing those individuals into contact with each other. They will figure out how to specifically reuse each others code.

*Side Note: C can embed a fully featured python environment, and Python can easily be extended by C libraries.

1

On the other hand, one could also argue that this makes code reuse more difficult. If team A uses language X and develops a nice script using the tool, team B can reuse the script only if they also work in language X.

As pointed out by others, if the functionality is non-trivial in nature, then I'd centralize it in a way that both languages can access (and therefore reuse) it.

My question is: from your experience, what is the global impact of having multiple APIs (potentially more people using the tool, but they can't share their code) or a single one (less people using the tool, but they can share their code)?

In general I've worked on products often that supported multiple languages dating back to even one that provided its own proprietary one (ancient cases before it was so popular to just embed things like Python or Lua).

And practically speaking you do tend to loosen the collaboration between the developers working in these different languages. They're typically going to develop different communities and mindsets and ways of thinking and doing things. The scripting community is going to think and approach things differently and potentially produce different little utility code to share than your Java JNI developer community or your native C++ plugin developer community. And there could be some redundancy of effort there between these separate groups whether it comes in the form of code duplication or something else (ex: even publishing books and documenting how to program your software).

On the positive side you expand your demographic of people contributing to the development and being able to use multiple languages can sometimes even be useful to a single developer. The embedded scripting language might be quicker to whip up something as well as easier to distribute and port (since there are no binaries to build) and safer (ex: no possibility of segfaulting), while the native code might be useful to reach for when performance is a legit concern.

Another team working with Python could reuse this new component with some minor adjustments while the team working with C would have to rewrite the whole component from scratch.

If that component is useful enough to be shared then I'd seek to avoid this restriction. In our case plugins written in script can execute/evaluate plugins written in native code and vice versa (those were always practical requirements in our case since our plugin architecture was about plugins registering components which would evaluate/execute each other, and the point was to make it unimportant what language was used to implement the plugins).

Where I found duplicated efforts was more in the realm of minor things that wouldn't improve productivity that much to seek to stamp out entirely like some minor duplication in documentation efforts, utility functions, sharing code snippets, etc, and just the looser collaboration you get from developers who practically speak and think in different programming languages.

If I can ramble a bit, I also don't always find it productive to zealously maximize code reuse rather than just pragmatically seeking to keep it within practical and maintainable limits. In the worst-case scenario you can see committees emerging and quarreling about how something rather trivial in functionality which barely saves people time to use should be designed in some central library (ex: developers arguing about whether a bounding box class should store centers and half-sizes or two min/max vectors, when they were getting a whole lot more work done just using separate classes in that case in their local projects), with more arguing, toe-stepping, and worst of all, find functionality being moved to central locations which hasn't been thoroughly tested and proven in production enough to be stable enough to direct a lot of dependencies in its direction, only for it to receive repeated central changes that break everything using it.

So these days I don't find it that useful to take code reuse to such a zealous level. I'm not talking about tolerating massive efforts in duplication, or bugs being duplicated, or anything like that, but just to relax it to a pragmatic level (like maybe let's not spend 2 hours in a developer meeting arguing about how to design a reusable bounding box class that satisfies everyone's needs perfectly when such unanimous agreement seems impossible, and not go crazy if a couple of developers develop one specific for their needs locally in their projects), and make reliability and testing of what the developers are producing the ultimate goal even if there's a little bit of redundancy in terms of what they might be doing.

0

You should look at this from a different perspective. The point of having a module with multiple interfaces on top is never reuse as such. Reuse in itself is never a goal, it is at best a result. The point is to have one implementation of some important piece of logic so it can be controlled and maintained centrally, by the right people, and it will always be the same logic used, by whatever user.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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