# API-Driven Development: design each module as an API

## Where API comes from

API abbreviates *Application Programming Interface*. The term predates the Web, and its central idea is even older: allowing a program to use a capability without depending on how it is built.

| Year | Milestone | Idea that remains |
|---|---|---|
| 1951 | Wilkes, Wheeler and Gill describe a [subroutine library for EDSAC](https://books.google.com/books?id=HwkuAAAAIAAJ) | The consumer needs a known way to invoke reusable behavior |
| 1968 | Cotton and Greatorex use *application program interface* in a [remote graphics system](https://doi.org/10.1145/1476589.1476661) | A stable interface can separate the program from different terminals and mechanisms |
| 1974 | Date and Codd compare [database programming interfaces](https://research.ibm.com/publications/the-relational-and-network-approaches-comparison-of-the-application-programming-interfaces) | The design of the interface impacts the design of the entire system |

The API, therefore, was not born as a synonym for an HTTP endpoint or a public service. Those are later mechanisms for expressing an interface. APIs are also the functions of a library, the calls of an operating system or any protocol that allows collaboration with an encapsulated capacity.

## How API-DD reinterprets it

API-DD preserves that historical function of the interface: separating the consumer from the mechanism. It expands that idea with an observation from Alan Kay: in a system capable of growing, it is more important to design how its modules communicate than to fix their internal properties. Kay placed message exchange at the core of Smalltalk, but his observation about modules and communication can be applied outside object-oriented programming ([original message from 1998](https://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html)).

API-DD takes the API from the outer boundary of an application to every modular relationship worthy of a contract. The conversation can be local or remote and expressed with functions, methods, events or HTTP. The mechanism changes; the separation between consumer and implementation remains.

This is a deliberate reinterpretation, not the claim that API has always meant exactly the same thing. From its history we take the separation between use and implementation; from Kay, the focus on messages between modules. That's where API-Driven Development comes from.

## Manifest

The software changes. Its contracts allow it to change without forcing each consumer to know its interior again.

1. **Interactions matter more than the internal form.** A module is understood by the conversations it offers and consumes.
2. **Vocabulary is part of the design.** Names express intentions, results and facts that other modules can understand.
3. **Visibility creates coupling.** The API shows what is necessary and keeps algorithms, coordination and representation replaceable.
4. **Autonomy extends to every result.** A complete and valid module fulfills its contract without asking the consumer to repair its state, and delivers results that do not share mutable references.
5. **The contract can be verified from outside.** Tests act as consumers and observe results, status or public messages.

These fundamentals can be applied recursively when a module is decomposed into other modules with their own contracts. API-DD does not prescribe an architecture, paradigm, or order of work. It offers a perspective for designing the conversations that hold the system together.

## Definition

> **API-Driven Development (API-DD) proposes designing each module as an API: making visible the messages it accepts, the guarantees it keeps, the details it hides and the APIs it needs.**

The starting point is not the class, the folder or the pattern that we are going to use. It is the contract through which one module collaborates with the others. Before solving its internals, we clarify what API it offers and what commitments must survive any correct implementation. It is a design perspective, not an architecture or set of mandatory rules.

In this book, **module** does not necessarily mean a language module, a package, a deployable service, or a file. It is an encapsulated part of the software that others use under a contract. Depending on the scale, it can be realized as a set of functions, a type, a package, a process, or a combination of these.

| Term | Use in API-DD |
|---|---|
| Module | Encapsulated part of software that provides behavior to others |
| Consumer | Actor, system or module that depends on that behavior |
| API | Protocol by which a module relates to its consumers |
| Message | Request, response or fact that crosses that API |
| Supplier | Implementation that satisfies the contract |

An API can be expressed with functions, methods, events, endpoints, or any other mechanism. The important thing is the conversation, not its syntax.

## Design the API

Looking at a module as an API makes few but concrete questions visible:

1. Who consumes it and why?
2. What messages can you send it?
3. What results, errors, state or effects can you observe?
4. What guarantees are maintained between calls?
5. What details should remain hidden?
6. What other APIs does the module consume?

These answers form the contract. The signature is only its most visible representation.

## A small example

Let's assume a module that applies a style to a text:

```text
Formatter.Format(Text, Style) → FormattedText | UnsupportedStyle
```

`Formatter` is the module and `Format` is a message from its API. `Text`, `Style`, `FormattedText` and `UnsupportedStyle` form the contract vocabulary. It is important to specify what they mean and what the consumer can do with them, but they are not independent APIs simply because they appear in the signature.

The contract may promise that:

- a supported style produces formatted text;
- an unknown style returns a distinguishable error;
- the original text does not change;
- the result does not reveal the library used internally.

The consumer does not need to know whether the provider uses a template, an intermediate tree, or an external library. Those decisions may change as long as the guarantees are maintained.

## Example in Go

Go can express the conversation using an interface and a distinguishable error.

```go
import "errors"

type Text string
type Style string
type FormattedText string

var ErrUnsupportedStyle = errors.New("unsupported style")

type Formatter interface {
    Format(Text, Style) (FormattedText, error)
}
```

The representation could change as long as `Formatter`, `Format` and the meaning of `ErrUnsupportedStyle` retain the contract.

## One way to apply it

A possible sequence to design a change with API-DD:

1. Identify the affected modules and their consumers.
2. Describe the conversation that each consumer needs.
3. Defines messages, vocabulary and observable guarantees.
4. Separate the contract from internal decisions.
5. Repeat the analysis only for internal modules with their own relationships.
6. Implement and test the contract without setting an unnecessary internal path.

API-DD is not a substitute for domain modeling, architecture, or TDD. It helps to specify how the modules that these disciplines discover collaborate.

> **API-DD allows you to view each module as an API and keep its implementation free.**
