Thin vs. Fat APIs

APIs are like engineered fishing holes. You either design one to be fished by a user for helper functions, or you make the user stock it with their own data to get custom behavior.

This is related to the size of facilities the library supplies. Rich APIs and Convenience Libraries have a tendency to be broad (many functions) and shallow (small objects). Narrow and deep functionality can sometimes be found with Minimal APIs.

Rich APIs are desirable becuase they offer a maximal amount of public functions from which to choose and minimal delegation control to a library. The downside is you use only 1% of what is in the library, but include this fat at run-time. Using rich APIs not only creates fat binaries (an actual problem nowadays) but also prevents you from writing only small amounts of comparatively simple code that you use often.

Thin APIs are desirable because they minimize the number of public functions and maximize delegation to a library. You're using a 99% of the code, but must live with the behavior of the library. This creates thin binaries, and can save you from writing large programs that you run only a few times. Those programs may not run exactly the way you want, but that is a problem with all libraries.

Which is more programmer-efficient?

An API user uses a library in the first place to minimize writing code. When you offer many small functions attached to manipulating a small object, you tend to defeat that purpose by increasing user dependency and offering only the illusion of delegating work. The user still ends-up writing code for large facilities.

In either case, the value of using libraries is measured by the amount of work saved in coding time. It's better to Code your own String class and use it a million times. It's less better to code your own XML parser that you use only once.

In designing a library, if you take the view that it serves a purpose by offering major facilities, and you recognize the user signs over control to the library to perform all functions related to those facilities, the concept of less is more (aka: minimal) becomes important.

Minimalism implies offering only a few public method calls - ideally not much outside of initialization, shutdown and configuration. However, if an API is well-designed, it also means that user is given control by data-oriented configuration.

Data-oriented configuration comes in the form of compile-time configuration "knobs" representing data inputs that can be set by the API user to customize special behavior of the facility offered. Designing an API in this way means writing quite a bit of support code, perhaps doubling the amount of original code to get the thing functional in the first place.

Obviously, offering an engineered system of control to users is very different than exposing a simple bucket of loosely-related helper functions centered on a frequently used, easily-programmed things. To design a system, you're not offering a rich API or convenience library but more like a full-fledged, programmable application module.

In libraries like these, the user hands control over to your code to perform a major application function they would rather not write. Simplified data input of configuration rather than a rich functional interface represents a higher-level of design consideration.

Your library offers a limited set of knobs. The user sets them according to preference. Set and forget.