ADR-3 concluded that a full-duplex communication channels are desirable to interact with a reactive system.
The Client API communicates several types of messages to clients. Currently this ranges from node-level
PeerConnected, over head-specific
HeadIsOpento messages about transactions like
TxValid. These messages are all of type
Current capabilities of the API:
Clients can retrieve the whole history of
StateChangedmessages or opt-out using a query parameter - all or nothing.
There is a welcome message called
Greetingswhich is always sent, that contains the last
There exists a
ClientInput, which will respond with a
GetUTxOResponsecontaining the confirmed UTxO set in an open head, or (!) the currently committed UTxO set when the head is initializing.
jsonencoded, clients can choose choose between
jsonor binary (
cbor) output of
transactionfields in several of these using a query parameter.
Many of these features have been added in a "quick and dirty" way, by monkey patching the encoded JSON.
The current capabalities even do not satisfy all user needs:
Need to wade through lots of events to know the latest state (except the very basic
Need to poll
GetUTxOor aggregate confirmed transactions on client side to know the latest UTxO set for constructing transactions.
Inclusion of the whole UTxO set in the head is not always desirable and filtering by address would be beneficial. (not addressed in this ADR though, relevant discussion #797)
As ADR-15 also proposes, some clients may not need (or should not have) access to administrative information.
It is often a good idea to separate the responsibilities of Commands and Queries (CQRS), as well as the model they use.
GetUTxOResponsemessages as they advocate a request/response way of querying.
ClientInputdata is actually a
ClientCommand(renaming them) and that
projectionsof the internal event stream (see ADR-24) into read
modelson the API layer.
Compose a versioned (
/v1) API out of resource
models, which compartmentalize the domain into topics on the API layer.
A resource has a
modeltype and the latest value is the result of a pure
projectionfolded over the
StateChangedevent stream, i.e.
project :: model -> StateChanged -> model.
Each resource is available at some HTTP path, also called "endpoint":
GETrequests must respond with the latest state in a single response.
Upgrade: websocketheaders must start a websocket connection, push the latest state as first message and any resource state updates after.
Other HTTP verbs may be accepted by a resource handler, i.e. to issue resource-specific commands. Any commands accepted must also be available via the corresponding websocket connection.
Acceptrequest headers can be used to configure the
Content-Typeof the response
All resources must provide
Some resources might support more content types (e.g. CBOR-encoded binary)
Query parameters may be used to further configure responses of some resources. For example,
?address=<bech32>could be used to filter UTxO by some address.
Keep the semantics of
/, which accepts websocket upgrade connections and sends direct/raw output of
/, while accepting all
ServerOutputalso in terms of the
Example resource paths + HTTP verbs mapped to existing things to demonstrate the effects of the decision points above. The mappings may change and are to be documented by an API specification instead.
|last confirmed snapshot utxo
|confirmed snapshot txs
NewTx + responses
NewTx + responses
|current protocol parameters
|a list of peers
|node version as in
Multiple heads are out of scope now and hence paths are not including a
<headId> variable section.
Clear separation of what types are used for querying and gets subscribed to by clients and we have dedicated types for sending data to clients
Changes on the querying side of the API are separated from the business logic.
Clients do not need to aggregate data that is already available on the server side without coupling the API to internal state representation.
Separation of Head operation and Head usage, e.g. some HTTP endpoints can be operated with authentication.
Clients have a fine-grained control over what to subscribe to and what to query.
Versioned API allows clients to detect incompatibility easily.
Need to rewrite how the