Contracts
A contract defines what a request accepts and what a response returns. It is the boundary between the outside world and domain logic.
What Contracts Do
Every contract handles:
- Validate requests — coerce values into declared types, enforce constraints, reject invalid data with structured errors
- Shape responses — define what the API returns, checked in development
- Describe the API — the same definitions that execute at runtime are used to generate exports
Contracts are the most fundamental building block in Apiwork. They can be written entirely by hand.
A Minimal Contract
class PostContract < Apiwork::Contract::Base
action :create do
request do
body do
string :title
string :body
end
end
end
endThe create action expects a request body with title and body, both strings. Invalid requests are rejected before the controller runs.
Naming Convention
Apiwork resolves contracts from the controller name:
| Controller | Contract |
|---|---|
Api::V1::PostsController | Api::V1::PostContract |
Api::V1::CommentsController | Api::V1::CommentContract |
Singular form of the controller name.
Representation Mode
Connect a contract to a representation to enter representation mode:
class PostContract < Apiwork::Contract::Base
representation PostRepresentation
endIn this mode, the contract is driven by its representation through an adapter. Request shapes, response shapes, filter types, and sort options are derived automatically. All generated behavior remains fully customizable.
Abstract Contracts
abstract! marks a contract as abstract when it should not be used directly:
class ApplicationContract < Apiwork::Contract::Base
abstract!
import SharedTypes, as: :shared
end
class InvoiceContract < ApplicationContract
representation InvoiceRepresentation
endAbstract contracts serve as base classes for shared imports and configuration. Subclasses automatically become non-abstract.
Next Steps
- Actions — defining request and response shapes per action
- Types — reusable objects, unions, enums, and fragments
- Imports — sharing types between contracts
- Validation — the request lifecycle and error handling
See also
- Contract::Base reference — all contract methods and options