You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm starting this discussion as a place to collect the various thoughts I've had recently about what a better REST API might look like.
Some general ideas about standards
Here are some of the standards that have come up in the past:
GraphQL
Pros:
very flexible and powerful
very good tooling, the standard is mature and well-maintained
aligns well with the graph-like structure of contract history and blockchain
Schema has built-in support for union types
Well suited for APIs that are primarily read-based
Supports subscriptions for event streaming
Cons
Explicitly does not support fixpoint expansion of mutually recursive data types - kind of a deal-breaker for datum, metadata, and contract structures.
Not as widely adopted or understood as REST, may be a learning curve
Error reporting standards beyond structural schema validation are not very clear. or general.
Due to the way unions are represented in the schema, the standard JSON representation of semantics types are incompatible - meaning a GraphQL-specific encoding is required.
JSON API
Pros:
Basic REST with more structure
Very explicit support for links and relationships
Good standards for error reporting
Cons:
Better suited to CRUD APIs. The complexity added to support updating and deleting adds nothing to a primarily read-based API
OData
Pros:
Comparable flexibility to GraphQL
Very powerful filtering capabilities
Unlike GraphQL, it's REST (though REST on steroids)
Cons:
Quite complicated
Non-standard URI path formating with function call-like syntax
Assumptions
The current state of the ledger is more important than past states. This influences the choices of entities and how they are related.
History is still important. The relationships make discovering history easy.
People want to use hosted services, not host services themselves.
a. This does not exclude enterprise solutions hosting their own infrastructure - this would still be considered a hosted white-label solution.
Schema
As a matter of principle, a single resource may be identified by multiple URIs. For example, a single resource may be queryable as a top-level resource or a sub-resource of another.
TransactionOutput
Refers to an output of a transaction
Identifier
Transaction ID + index of output.
Attributes
address the address where the contract lives.
assets The assets in the transaction output.
datumHash optional hash of the datum in the output
datum optional datum, if present in the transaction or inlined in the output.
bytes hex-encoded bytes of the datum
value structured object representing the datum.
referenceScriptHash optional reference script hash in the output
referenceScript optional reference script bytes in the output
Relationships
transaction Cardinality: exactly 1. The Transaction that created the output
consumer Cardinality: zero or 1. The TransactionInput that consumed the output
ContractOutput
A variant of a transaction output to a Marlowe validator and contains a valid Marlowe datum.
Identifier
Inherited from TransactionOutput
Attributes
Inherited from TransactionOutput with:
datumHash and datum are not optional
scriptHash the script hash from the address
contract the contract terms (corresponds to the marloweContract field of the datum)
state the contract state (corresponds to the marloweState field of the datum)
params the contract params (corresponds to the marloweParams field of the datum)
metadata The Marlowe metadata, if provided in the transaction.
Relationships
Inherited from TransactionOutput with:
consumer refers to a ContractInput
thread Cardinality: exactly 1. The Thread to which the contract belongs
PayoutOutput
A variant of a transaction output to a payout validator and contains a valid payout datum.
Identifier
Inherited from TransactionOutput
Attributes
Inherited from TransactionOutput with:
datumHash and datum are not optional
scriptHash the script hash from the address
roleToken the role token policy ID and name from the datum
Relationships
Inherited from TransactionOutput with:
consumer refers to a WithdrawalInput
thread Cardinality: exactly 1. The Thread from which the payout was sent.
Transaction
Refers to an event within a block that spends the outputs of previous transactions and produces new outputs. In the context of the Marlowe API, a transaction
Identifier
A 32-bit hash encoded as 64 hexadecimal characters.
Attributes
assets total assets in the output
totalCollateral total collateral in lovelace
index transaction index within block
fees fees in lovelace
invalidBefore lower bound of the tx validity range
invalidHereafter upper bound of the tx validity range
mints mints or burns in the transaction with minting witnesses
Relationships
inputs Cardinality: 1 or more - inputs of the transaction with spending witnesses
outputs Cardinality: 1 or more - Outputs of the transaction
collateralInputs Cardinality: 0 or more - Collateral inputs of the transaction
collateralOutput Cardinality: 0 or 1 - Return collateral TransactionOutput
block Cardinality: exactly 1 - the block to which this transaction belongs
Block
Refers to a block in the chain with a set of transactions.
Identifier
A 32-bit hash encoded as 64 hexadecimal characters.
Attributes
slot slot number
blockNo block's index in the chain
time slot number converted to UTC timestamp
epoch epoch number
epochSlot slot within the epoch
Relationships
previous Cardinality: 0 or 1 - The previous block unless this is the genesis block
next Cardinality: 0 or 1 - The next block
transactions Cardinality: 0 or more - The transactions in the block
TransactionInput
Refers to the consumption of a TransactionOutput by a Transaction.
Identifier
The ID of the consumed TransactionOutput
Attributes
referenceScriptHash optional reference script hash in script witness
script optional script in script witness
hash optional script hash in script witness
bytes optional script bytes in script witness
datum optional datum in script witness
hash optional datum hash in script witness
bytes optional datum bytes in script witness
redeemer optional redeemer in script witness
hash optional redeemer hash in script witness
bytes optional redeemer bytes in script witness
Relationships
transaction Cardinality: exactly 1. The Transaction of the input
consumed Cardinality: exactly 1. The TransactionOutput that the input consumes
ContractInput
A variant of a transaction input from a Marlowe validator that contains a valid Marlowe datum and redeemer.
Identifier
Inherited from TransactionInput
Attributes
Inherited from TransactionInput with:
(referenceScriptHash|script), datum, and redeemer are not optional
inputs the Marlowe semantic inputs - decoded from the redeemer with Merkle continuations inlined.
Relationships
Inherited from TransactionInput with:
consumed refers to a ContractOutput
thread Cardinality: exactly 1. The Thread to which the contract belongs
WithdrawalInput
A variant of a transaction input from a payout validator that contains a valid payout datum.
Identifier
Inherited from TransactionInput
Attributes
(referenceScriptHash|script) and datum are not optional
redeemer is null
Relationships
Inherited from TransactionInput with:
consumed refers to a PayoutOutput
thread Cardinality: exactly 1. The Thread from which the payout was sent
Endpoints
All the following are GET only.
Standard Query Parameters
include which related resources to include in the response. The allowed values are any relationship of
the requested resource and arbitrary subresources thereof.
fields[TYPE], which fields (attributes and relationships) will be included in the response by type.
sort how to sort the results. Value can be a path to a specific field in the resource (including sub resources), ascending by default, descending when - is the prefix.
filter[field], filter by field, where field is a path to a field in the resource. Values are comma-separated lists of allowed values. If field is prefixed with a ! then the values become disallowed valued. Specifying the same filter field in multiple parameters requires they both hold. I.e. to or values, use the comma-separated list, to and values, use multiple parameters. For collections, the pseudo-paths "any" and "all" can be used to match on collections where either any or all items fulfill the query.
from which value to start a page from. Must be the same fields specified by sort.
limit how many results to include
offset how many results from from to start from.
/blocks
List all blocks.
Default sorting - descending by blockNo
/blocks/{blockId}
Get a block
Params
blockId the ID of the block.
/blocks/{blockId}/next
Get next block.
Params
blockId the ID of the block.
/blocks/{blockId}/previous
Get previous block.
Params
blockId the ID of the block.
/blocks/{blockId}/transactions
Get transactions in a block.
Params
blockId the ID of the block.
/transactions/{txId}
Get a transaction.
Params
txId the ID of the transaction
/transactions/{txId}/inputs
Get the inputs for a transaction.
Params
txId the ID of the transaction
/transactions/{txId}/inputs/{index}
Get an input for a transaction.
Params
txId the ID of the transaction
index the index of the input in the transaction
/transactions/{txId}/outputs
Get the outputs for a transaction.
Params
txId the ID of the transaction
/transactions/{txId}/outputs/{index}
Get an output for a transaction.
Params
txId the ID of the transaction
index the index of the output in the transaction
/transactions/{txId}/collateralInputs
Get the collateral inputs for a transaction.
Params
txId the ID of the transaction
/transactions/{txId}/collateralInputs/{index}
Get a collateral input for a transaction.
Params
txId the ID of the transaction
index the index of the collateral input in the transaction
/transactions/{txId}/collateralOutput
Get the collateral output for a transaction.
Params
txId the ID of the transaction
/transactions/{txId}/block
Get the block of a transaction.
Params
txId the ID of the transaction
/contracts
Get unspent contract outputs.
/contracts/{contractId}
Get a contract output.
Params
contractId the ID of the transaction output that holds the contract.
/contracts/{contractId}/actions/{timeRange}
Get available actions for a contract within a time range.
Params
contractId the ID of the transaction output that holds the contract.
timeRange the time range during which the actions are valid in the form startTime..endTime.
/contracts/{contractId}/thread
Get the thread of a contract.
Params
contractId the ID of the transaction output that holds the contract.
/accounts/{accountId}/contracts
Get unspent contract outputs associated with a stake address. Associated contracts are:
Contracts with either action parties or accounts which:
If an address, match the given stake address
If a role, have a matching role token belonging to an address associated with the stake address.
Params
accountID the stake address of the reward account.
/payouts
Get unspent payout outputs.
/payouts/{payoutId}
Get a payout output.
Params
payoutId the ID of the transaction output that holds the payout.
/payouts/{payoutId}/thread
Get the thread of a payout.
Params
payoutId the ID of the transaction output that holds the payout.
/accounts/{accountId}/payouts
Get unspent payout outputs associated with a stake address. Associated payouts are ones which the stake address holds the required role token to withdraw.
Params
accountID the stake address of the reward account.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I'm starting this discussion as a place to collect the various thoughts I've had recently about what a better REST API might look like.
Some general ideas about standards
Here are some of the standards that have come up in the past:
Assumptions
a. This does not exclude enterprise solutions hosting their own infrastructure - this would still be considered a hosted white-label solution.
Schema
As a matter of principle, a single resource may be identified by multiple URIs. For example, a single resource may be queryable as a top-level resource or a sub-resource of another.
TransactionOutput
Refers to an output of a transaction
Identifier
Transaction ID + index of output.
Attributes
Relationships
ContractOutput
A variant of a transaction output to a Marlowe validator and contains a valid Marlowe datum.
Identifier
Inherited from
TransactionOutput
Attributes
Inherited from
TransactionOutput
with:marloweContract
field of the datum)marloweState
field of the datum)marloweParams
field of the datum)Relationships
Inherited from
TransactionOutput
with:ContractInput
PayoutOutput
A variant of a transaction output to a payout validator and contains a valid payout datum.
Identifier
Inherited from
TransactionOutput
Attributes
Inherited from
TransactionOutput
with:Relationships
Inherited from
TransactionOutput
with:WithdrawalInput
Transaction
Refers to an event within a block that spends the outputs of previous transactions and produces new outputs. In the context of the Marlowe API, a transaction
Identifier
A 32-bit hash encoded as 64 hexadecimal characters.
Attributes
Relationships
TransactionOutput
Block
Refers to a block in the chain with a set of transactions.
Identifier
A 32-bit hash encoded as 64 hexadecimal characters.
Attributes
Relationships
TransactionInput
Refers to the consumption of a
TransactionOutput
by a Transaction.Identifier
The ID of the consumed
TransactionOutput
Attributes
Relationships
ContractInput
A variant of a transaction input from a Marlowe validator that contains a valid Marlowe datum and redeemer.
Identifier
Inherited from
TransactionInput
Attributes
Inherited from
TransactionInput
with:Relationships
Inherited from
TransactionInput
with:ContractOutput
WithdrawalInput
A variant of a transaction input from a payout validator that contains a valid payout datum.
Identifier
Inherited from
TransactionInput
Attributes
Relationships
Inherited from
TransactionInput
with:PayoutOutput
Endpoints
All the following are GET only.
Standard Query Parameters
include
which related resources to include in the response. The allowed values are any relationship offields[TYPE]
, which fields (attributes and relationships) will be included in the response by type.sort
how to sort the results. Value can be a path to a specific field in the resource (including sub resources), ascending by default, descending when-
is the prefix.filter[field]
, filter by field, wherefield
is a path to a field in the resource. Values are comma-separated lists of allowed values. Iffield
is prefixed with a!
then the values become disallowed valued. Specifying the same filter field in multiple parameters requires they both hold. I.e. toor
values, use the comma-separated list, toand
values, use multiple parameters. For collections, the pseudo-paths "any" and "all" can be used to match on collections where either any or all items fulfill the query.from
which value to start a page from. Must be the same fields specified bysort
.limit
how many results to includeoffset
how many results fromfrom
to start from./blocks
List all blocks.
Default sorting - descending by blockNo
/blocks/{blockId}
Get a block
Params
/blocks/{blockId}/next
Get next block.
Params
/blocks/{blockId}/previous
Get previous block.
Params
/blocks/{blockId}/transactions
Get transactions in a block.
Params
/transactions/{txId}
Get a transaction.
Params
/transactions/{txId}/inputs
Get the inputs for a transaction.
Params
/transactions/{txId}/inputs/{index}
Get an input for a transaction.
Params
/transactions/{txId}/outputs
Get the outputs for a transaction.
Params
/transactions/{txId}/outputs/{index}
Get an output for a transaction.
Params
/transactions/{txId}/collateralInputs
Get the collateral inputs for a transaction.
Params
/transactions/{txId}/collateralInputs/{index}
Get a collateral input for a transaction.
Params
/transactions/{txId}/collateralOutput
Get the collateral output for a transaction.
Params
/transactions/{txId}/block
Get the block of a transaction.
Params
/contracts
Get unspent contract outputs.
/contracts/{contractId}
Get a contract output.
Params
/contracts/{contractId}/actions/{timeRange}
Get available actions for a contract within a time range.
Params
startTime..endTime
./contracts/{contractId}/thread
Get the thread of a contract.
Params
/accounts/{accountId}/contracts
Get unspent contract outputs associated with a stake address. Associated contracts are:
Params
/payouts
Get unspent payout outputs.
/payouts/{payoutId}
Get a payout output.
Params
/payouts/{payoutId}/thread
Get the thread of a payout.
Params
/accounts/{accountId}/payouts
Get unspent payout outputs associated with a stake address. Associated payouts are ones which the stake address holds the required role token to withdraw.
Params
/threads/{threadId}
Get all transactions in a contract thread.
Params
Beta Was this translation helpful? Give feedback.
All reactions