# Foundation 1. Recursion

## An API can be conceptualized as a module

To design an API, it is useful to conceptualize it as a module seen from the outside. The module assembles a capability and preserves its implementation; the API is the boundary by which others collaborate with it.

They are not exactly the same. A module can offer more than one conversation to different consumers and also consume other APIs. Equivalence serves as a design tool: when a relevant API appears, we look for the module responsible for supporting its contract.

```text
module
├── API offered → consumers
├── hidden implementation
└── Consumed APIs → other modules
```

The module can be materialized as a function, a type, a package, a process, or several coordinated elements. Its technical form does not determine its conceptual scale.

## Interactions are the focus

API-DD focuses on what happens between modules: messages, responses, errors, effects and guarantees. This look follows Alan Kay's idea presented in the introduction: systems grow better when you design how their modules communicate, not when their entire interior is fixed in advance.

Looking at the interactions allows you to ask specific questions:

- What does the consumer need to express?
- What module is responsible for that capacity?
- What can be observed on the other side of the limit?;
- What conversation does the module have with its own suppliers?;
- What decisions can be changed without affecting others?

The algorithm is still important, but it belongs to another level. First we distinguish what must survive any correct implementation and then we choose how to achieve it.

## All fundamentals are repeated

When a module is decomposed into modules with their own contracts, the five fundamentals can be applied again at each boundary:

| Foundation | Question that reappears |
|---|---|
| Recursion | What modules and conversations exist at this scale? |
| Vocabulary | What do their names and messages mean? |
| Visibility | What does each consumer need to know? |
| Autonomy | Can the module fulfill its contract and deliver results without shared mutable state? |
| Testability | Can it be verified by public observations? |

Recursion does not convert every parameter, helper, or structure into another API. `Value`, `Result`, or `Error` are part of the vocabulary of a message. They are only considered modules when they gather behavior, have consumers or need to evolve through their own contract.

## Where to continue and where to stop

The perspective can be applied again when at least one of these signs appears:

- another consumer needs to use the capacity directly;
- there is a responsibility with its own guarantees;
- the component can evolve or be replaced independently;
- an interaction crosses a relevant technical or organizational boundary.

It stops when the decision only explains how the current module works. A loop, index, or helper function does not need its own API if no external relationship depends on it.

This avoids confusing recursion with an infinite hierarchy of interfaces. The goal is to recognize useful boundaries, not to fabricate layers.

## Example in Go

A `Pipeline` offers an API and consumes the API of each `Stage`. The slice traversal remains within its implementation.

```go
type Stage interface {
    Apply([]byte) ([]byte, error)
}

type Pipeline struct {
    stages []Stage
}

func (p Pipeline) Run(value []byte) ([]byte, error) {
    var err error
    for _, stage := range p.stages {
        value, err = stage.Apply(value)
        if err != nil {
            return nil, err
        }
    }
    return value, nil
}
```

There may be many implementations of `Stage`. Each can be reviewed again as a module, while the slice path remains a `Pipeline` detail.

## Hands-on review

1. Name the API you are looking at and the module that answers for it.
2. Identify your consumers and the APIs they consume.
3. Repeat the analysis only in collaborations with their own contract.
4. Keep algorithms and helpers within the module that uses them.
5. Check that the decomposition clarifies a real relationship.

> **Recursion follows conversations between modules, not each line of code.**
