Modeling Web API Results with Pattern Matching
An API operation can return a union that lists its domain outcomes:
type CreateUserResult =
Created { id: int }
| ValidationFailed { message: string }
| DuplicateEmail { email: string }
| DatabaseUnavailable
One function maps each outcome to an HTTP response:
fn json(status, body) = HttpResponse {
status: status,
headers: "Content-Type: application/json",
contentType: "application/json",
streamFd: -1,
isComplete: true,
partialBody: body
}
fn toResponse(result) = match result {
Created { id } => json(201, "{\"id\": ${id}}")
ValidationFailed { message } => json(400, "{\"error\": \"${message}\"}")
DuplicateEmail { email } => json(409, "{\"error\": \"${email} is already registered\"}")
DatabaseUnavailable => json(503, "{\"error\": \"try again later\"}")
}
The checker rejects a match that omits a variant, so adding a variant points at every match that needs a new case.
HTTP, parsing and FFI code can still fail; this keeps the modeled outcomes in ordinary data and their HTTP mapping in one function.
See the HTTP specification and pattern-matching specification for the implemented contracts.