# Fundamento 1. Recursión

## Una API puede conceptualizarse como un módulo

Para diseñar una API resulta útil conceptualizarla como un módulo visto desde fuera. El módulo reúne una capacidad y conserva su implementación; la API es el límite por el que otros colaboran con él.

No son exactamente lo mismo. Un módulo puede ofrecer más de una conversación a consumidores diferentes y también consumir otras APIs. La equivalencia sirve como herramienta de diseño: cuando aparece una API relevante, buscamos el módulo responsable de sostener su contrato.

```text
módulo
├── API ofrecida → consumidores
├── implementación oculta
└── APIs consumidas → otros módulos
```

El módulo puede materializarse como una función, un tipo, un paquete, un proceso o varios elementos coordinados. Su forma técnica no determina su escala conceptual.

## El interés está en las interacciones

API-DD pone el interés en lo que ocurre entre módulos: mensajes, respuestas, errores, efectos y garantías. Esta mirada sigue la idea de Alan Kay presentada en la introducción: los sistemas crecen mejor cuando se diseña cómo se comunican sus módulos, no cuando se fija de antemano todo su interior.

Mirar las interacciones permite formular preguntas concretas:

- ¿qué necesita expresar el consumidor?;
- ¿qué módulo responde por esa capacidad?;
- ¿qué puede observarse al otro lado del límite?;
- ¿qué conversación mantiene el módulo con sus propios proveedores?;
- ¿qué decisiones pueden cambiar sin afectar a los demás?

El algoritmo sigue siendo importante, pero pertenece a otro nivel. Primero se distingue qué debe sobrevivir a cualquier implementación correcta y después se elige cómo conseguirlo.

## Todos los fundamentos se repiten

Cuando un módulo se descompone en módulos con contratos propios, los cinco fundamentos pueden aplicarse de nuevo en cada límite:

| Fundamento | Pregunta que reaparece |
|---|---|
| Recursión | ¿Qué módulos y conversaciones existen en esta escala? |
| Vocabulario | ¿Qué significan sus nombres y mensajes? |
| Visibilidad | ¿Qué necesita conocer cada consumidor? |
| Autonomía | ¿Puede el módulo cumplir su contrato y entregar resultados sin estado mutable compartido? |
| Testeabilidad | ¿Puede verificarse mediante observaciones públicas? |

La recursión no convierte cada parámetro, helper o estructura en otra API. `Value`, `Result` o `Error` forman parte del vocabulario de un mensaje. Solo pasan a considerarse módulos cuando reúnen comportamiento, tienen consumidores o necesitan evolucionar mediante un contrato propio.

## Dónde continuar y dónde detenerse

La perspectiva puede repetirse cuando aparece al menos una de estas señales:

- otro consumidor necesita usar la capacidad directamente;
- existe una responsabilidad con garantías propias;
- el componente puede evolucionar o sustituirse de forma independiente;
- una interacción cruza un límite técnico u organizativo relevante.

Se detiene cuando la decisión solo explica cómo trabaja el módulo actual. Un bucle, un índice o una función auxiliar no necesitan una API propia si ninguna relación externa depende de ellos.

Esto evita confundir recursión con una jerarquía infinita de interfaces. El objetivo es reconocer límites útiles, no fabricar capas.

## Ejemplo en Go

Un `Pipeline` ofrece una API y consume la API de cada `Stage`. El recorrido del arreglo permanece dentro de su implementación.

```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
}
```

Pueden existir muchas implementaciones de `Stage`. Cada una puede revisarse otra vez como módulo, mientras que el recorrido del slice sigue siendo un detalle de `Pipeline`.

## Revisión práctica

1. Nombra la API que estás observando y el módulo que responde por ella.
2. Identifica sus consumidores y las APIs que consume.
3. Repite el análisis solo en colaboraciones con contrato propio.
4. Mantén algoritmos y helpers dentro del módulo que los utiliza.
5. Comprueba que la descomposición aclara una relación real.

> **La recursión sigue las conversaciones entre módulos, no cada línea de código.**
