andersch.dev

<2025-10-09 Thu>

API (Application Programming Interface)

An Application Programming Interface (API) defines functions, data types, and conventions to let software components communicate with each other at the source code level.

API Characteristics

Granularity (A or BC)

  • At what granularity does the API operate?
  • Can it work on a smaller one by breaking down steps?
  • Useful for e.g. letting user insert own steps in between
  • Trade-off: Flexibility vs Simplicity
// A
UpdateOrientation(object);

// BC
orientation = GetOrientation(object);
change = GetOrientationChange(object);
SetOrientation(object, orientation + change);

Redundancy (A or B)

  • Enable doing the same thing different ways
  • Important to not force something on the user
  • More redundancy means more ways of doing the same thing
  • Trade-off: Convenience vs Orthogonality
SetOrientation3x3(object, matrix);   // A
SetOrientationQ(object, quaternion); // B

Coupling (A implies B)

  • Bundling things together without being able to separate them
  • No trade-off, but can be unavoidable
// hidden coupling
SetTime(globalTime);
UpdateObject(object);

// implicit lock
glBegin_()
glEnd_();

// coupling allocation and initialization
object = ConstructObject();

// coupling to a type
matrix = MakeMatrix(floatptr);
SetOrientationM(object, matrix);

Retention (A mirrors B)

  • API keeps copy of data that user is in charge of
  • Trade-off: Synchronization vs Automation
// api retains time
SetTime(globalTime);

// api retains hierarchy
SetParent(child, parent);
UpdateOrientation(child);

// api retains function calls
SetFileCallbacks(Open, Read, Close);
file = OpenFile(filename);

Flow Control (A invokes B)

  • Who is calling who?
  • No trade-off, simple is better
  • A: App calls Lib
  • B: App calls Lib calls App
  • C: App calls Lib calls App calls Lib…
/* stack traces */

// A
LibTestWidget
LibProcessWidget
GameProcessWidgets
GameUpdate

// B
GameHandleLibWidget
LibTestWidget
LibProcessWidget
GameProcessWidgets
GameUpdate

// C
LibWidgetChangeHeight
GameHandleLibWidget
LibTestWidget
LibProcessWidget
GameProcessWidgets
GameUpdate

API Design

Initially, users want low granularity and high retention. Later, users want high granularity and low retention.

In the beginning, all you want is results. In the end, all you want is control.

Checklist:

  • [ ] Write the API usage code first
  • [ ] Retained mode constructs have immediate-mode equivalents
  • [ ] Provide alternative API calls that do not use callbacks/inheritance
  • [ ] Do not require a datatype that the user already has
  • [ ] Non-atomic API calls can be broken down using atomic ones
  • [ ] All data should be transparent unless it is required to be opaque
  • [ ] API resource management (memory, file, string, etc.) is not forced on user
  • [ ] Library's file formats are optional
  • [ ] Full run-time source code is available

Resources for API Design