Why Contracts

This document explains why Azu uses explicit request and response contracts, and the benefits this pattern provides.

The Problem

In many frameworks, request handling is implicit:

# Rails controller
def create
  @user = User.new(user_params)
  # What is user_params?
  # What fields are allowed?
  # What validations apply?
end

private

def user_params
  params.require(:user).permit(:name, :email, :age)
  # Scattered across the file
  # Not type-safe
  # Validation elsewhere
end

Problems:

  • Input shape isn't clear

  • Validation is separate from definition

  • No compile-time checking

  • Easy to miss fields

The Contract Solution

Contracts make everything explicit:

Everything in one place:

  • Required fields

  • Types

  • Validation rules

  • Default values

API as Interface

Contracts define your API interface:

Request Contract = API Input

Reading this tells you exactly what the API accepts.

Response Contract = API Output

Reading this tells you exactly what the API returns.

Validation Colocation

Validation rules live with the data definition:

No hunting through multiple files.

Type-Safe Access

Contracts provide typed access:

No casting, no string parsing, no nil surprises.

Self-Documenting Code

Contracts document themselves:

New developers can understand the API by reading types.

Versioning

Contracts make versioning explicit:

Testing Benefits

Contracts are easy to test:

Code Generation

Contracts enable tooling:

Comparison

Aspect
Implicit (params)
Explicit (contracts)

Discoverability

Low

High

Type safety

None

Full

Validation

Scattered

Colocated

Documentation

Manual

Automatic

Testing

Complex

Simple

Refactoring

Risky

Safe

Trade-offs

More Boilerplate

Rigid Structure

Dynamic patterns are harder:

The Azu Philosophy

Contracts align with Azu's goals:

  1. Explicit over implicit - Clear code beats magic

  2. Compile-time over runtime - Catch errors early

  3. Documentation as code - Types don't lie

  4. Testing support - Easy to verify

See Also

Last updated

Was this helpful?