liveBook · Manning

Contract

As explained in Functional Design and Architecture: Examples in Haskell

An application programming interface is a defined contract through which software clients interact with a component or service.

An application programming interface (API) is a contract for communicating with a software component. It defines available operations, their inputs, outputs, and relevant types while keeping implementation details out of client code. Clients assemble provided building blocks without needing to know how each block works internally, so implementations can change without breaking the contract. section 1.3.2

An API addresses a practical design problem: native device calls, services, or libraries may expose inconsistent, low-level details that spread through an application. Calling them directly couples business logic to vendors, protocols, magic constants, and side effects. A higher-level API unifies access and places device-specific work behind an abstraction. section 1.3 section 1.3.1

A useful API design keeps the boundary focused:

  • Expose only the operations and types clients need; avoid leaking implementation-specific details. section 1.3.2 section 10.1.1
  • Give each interface a narrow responsibility, so unrelated concerns do not become required fields or methods. section 1.3.1 section 10.1.1
  • Let client code depend on the abstraction, then supply concrete implementations at assembly time. section 1.3.2
  • Treat multiple implementations as useful but not mandatory: even one implementation can decouple and simplify business logic. section 10.1.1
  • Use a shared HTTP schema when a client and server must agree on requests and responses. section 14.1

Sensor and connection boundary

A temperature observer can depend on an ISensor that supplies data, name, and data type, plus an IConnection that sends data. The observer reads from one and sends through the other without knowing whether the sensor is defective, how it converts measurements, or whether the destination is a server or database. Concrete thermometer and receiver implementations carry those details. This separation makes replacement and testing possible without rewriting the observer. section 1.3.1 section 1.3.2

APIs need not be object-oriented interfaces. In C, a stable public interface can consist of an opaque type and procedures. In functional designs, exported abstract types and functions can hide a subsystem implementation; a record of functions can serve as a service handle; and free monads can model domain-specific interface operations. These forms pursue the same boundary between client intent and implementation detail. section 1.4.1 section 3.3.3 section 4.2.2 section 6.1

A well-chosen API supports modularity, inversion of control, and testability. Business logic can receive a real implementation in production or a mock in a white-box test, while avoiding direct effects and bypasses around the boundary. APIs therefore help contain complexity rather than merely provide alternate implementations. section 15.2.1 section 1.6

Table 1.1 Spaceship API (view table figure)

Command

Native API function

Start boosters

int send(BOOSTERS, START, 0)

Stop boosters

int send(BOOSTERS, STOP, 0)

Start rotary engine

core::request::result
request_start(core::RotaryEngine)

Stop rotary engine

core::request::result
request_stop(core::RotaryEngine)

Compare raw spaceship commands with the need for a unified higher-level contract that shields application code from inconsistent native calls. section 1.3

How Functional Design and Architecture: Examples in Haskell covers it

How deep it goes
Defines APIs as implementation-independent contracts and develops object-oriented, imperative, functional, and HTTP forms.
Examples
Uses spaceship commands, sensor and connection interfaces, C opaque types, hardware handlers, loggers, and HTTP schemas.
What it assumes
Introduces API contracts through concrete interfaces while later functional forms assume familiarity with types, functions, and monads.
What you can do after
Evaluate/understand how to hide implementations, substitute dependencies, and design narrow contracts for testable business logic.
How it connects
Connects APIs with interfaces, inversion of control, modularity, dependency injection, Service Handle, free monads, and testing.

Also explained in

Compare how 44 books explain contract →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Design and Architecture: Examples in Haskell. The section links point to the parts of the book it draws on.