A simple REST API interface for Hyperledger Fabric blockchain network. Supported features:
- enroll, reenroll, register and list identities,
- discover the network for a given channel,
- query and invoke chaincode (with transient parameters support).
Fablo REST should work with any available Hyperledger Fabric network, however it is also integrated
with Fablo, a simple tool to generate the Hyperledger Fabric blockchain network
and run it on Docker. It is distributed as the Docker
image: ghcr.io/fablo-io/fablo-rest
.
Use Fablo REST in Docker compose file within the same Docker network as Hyperledger Fabric:
fablo-rest.org1.com:
image: ghcr.io/fablo-io/fablo-rest:0.1.2
environment:
- PORT=8000
- MSP_ID=Org1MSP
- FABRIC_CA_URL=http://ca.org1.com:7054
- FABRIC_CA_NAME=ca.org1.com
- AS_LOCALHOST=false
- DISCOVERY_URLS=grpc://peer0.org1.com:7060
- HFC_LOGGING={"debug":"console"}
ports:
- 8800:8000
depends_on:
- ca.org1.com
- peer0.org1.com
Start Fablo REST locally, connected to some Hyperedger Fabric network that has been started
on localhost
(+ use TLS):
npm install
npm run build
MSP_ID="Org2MSP" \
FABRIC_CA_URL="https://localhost:7054" \
FABRIC_CA_NAME="ca.org2.com" \
DISCOVERY_URLS="grpcs://localhost:7070,grpcs://localhost:7071" \
DISCOVERY_SSL_TARGET_NAME_OVERRIDES="peer0.org2.com,peer1.org2.com" \
DISCOVERY_TLS_CA_CERT_FILES="./some-path/org2.com/peers/peer0.org2.com/tls/ca.crt,./some-path/org2.com/peers/peer1.org2.com/tls/ca.crt" \
AS_LOCALHOST="true" \
npm start-dist
Start Fablo REST as a Docker container and join some Docker network:
docker run \
-e MSP_ID="Org1MSP" \
-e FABRIC_CA_URL="http://ca.org1.com:7054" \
-e FABRIC_CA_NAME="ca.org1.com" \
-e DISCOVERY_URLS="grpc://peer0.org1.com:7060,grpc://peer0.org2.com:7060" \
-e AS_LOCALHOST="false" \
-p "8000:8000" \
--network="$docker_network_name" \
-d \
--rm \
ghcr.io/fablo-io/fablo-rest:0.1.2
PORT
- the port under with Fablo REST will be available (default:8000
).MSP_ID
- a Membership Service Provider ID for the organization that runs the Fablo REST instance ( default:Org1MSP
).FABRIC_CA_URL
- an URL to Certificate Authority (CA) instance (default:http://localhost:7031
).FABRIC_CA_NAME
- the name of CA used by this Fablo REST instance (default:ca.org1.com
).AS_LOCALHOST
- whether the service discovery should convert discovered host names tolocalhost
. The variable should be set totrue
if the network starts with Docker compose (default:true
).DISCOVERY_URLS
- a comma-separated list of Anchor Peer URLs to be used as service discovery endpoins ( default:grpc://localhost:7060
).DISCOVERY_SSL_TARGET_NAME_OVERRIDES
- ifAS_LOCALHOST
variable is set totrue
and the Fabric network uses TLS. The variable should provide a comma-separated list of anchor peer names for each value fromDISCOVERY_URLS
variable. See also[ConnectOptions](https://hyperledger.github.io/fabric-sdk-node/release-2.2/global.html#ConnectOptions)
from Fabric Node.js SDK. By default the variable is empty.DISCOVERY_TLS_CA_CERT_FILES
- if the Fabric network uses TLS, the variable should provide a comma separated paths to PEM certificates of Anchor Peers specified inDISCOVERY_URLS
variable. Paths should be available for Fablo REST container, so don't forget to mount required volumes. By default the variable is empty.HFC_LOGGING
- contains a stringified JSON that describes the Logging levels and targets for both Fablo REST and Node.js SDK that Fablo REST uses, see some examples.
Enrolls an identity in the CA and returns Fablo REST authorization token.
curl --request POST \
--url http://localhost:8000/user/enroll \
--header 'Authorization: Bearer ' \
--data '{"id": "<user-id>", "secret": "<user-secret>"}'
{
"token": "<authorization-token>"
}
Reenrolls an identity in the CA, returns new Fablo REST authorization token and invalidates the previous one.
curl --request POST \
--url http://localhost:8000/user/reenroll \
--header 'Authorization: Bearer <authorization-token>'
{
"token": "<new-authorization-token>"
}
Registers an identity in the CA. Requires an admin user.
curl --request POST \
--url http://localhost:8000/user/register \
--header 'Authorization: Bearer <authorization-token>'
--data '{"id": "<user-id>", "secret": "<user-secret>"}'
{
"message": "ok"
}
Returns a list of identities saved in the CA. Requires an admin user.
curl --request GET \
--url http://localhost:8000/user/identities \
--header 'Authorization: Bearer <authorization-token>'
{
"response": {
"caname": "<ca-name>",
"identities": [
{
"affiliation": "<user-affiliation>",
"id": "<user-id>",
"type": "<user-type>",
"attrs": "<an-array-of-user-atrributes>",
"max_enrollments": "<number>"
},
...
]
}
}
Runs service discovery for given channel
and returns the discovery results. It uses kind of "round robin" strategy for
the discovery. If a discovery peer is not available for discovery for the given channel, it tries another one.
curl --request POST \
--url http://localhost:8000/discover/my-channel1 \
--header 'Authorization: Bearer <authorization-token>'
JSON with discovery results, containing MSPs, orderers and peers by organizations. This is quite a complex object, see the example in the discovery e2e tests.
Invokes or queries the chaincode
on a given channel
. It uses MSPID_SCOPE_ALLFORTX
strategy for invoke
and MSPID_SCOPE_ROUND_ROBIN
strategy for query.
curl --request POST \
--url http://localhost:8000/invoke/my-channel1/chaincode1 \
--header 'Authorization: Bearer <authorization-token>'
--data "{
\"method\": \"<ContractClass:method>\",
\"args\": [
\"arg1\",
\"arg2\",
...
],
\"transient\": {
\"<key>\": \"<value>\",
...
}
}"
You may use invoke
and query
interchangeably (the rest of the request is the same), but remember that query
requests do not modify the blockchain.
Field transient
is optional, and it contains an object with string keys and string values. You don't need to encode
the stings in Base64 format, Fablo REST will do it for you.
A response from the chaincode. It will contain a JSON object, string or another value returned by the chaincode:
{
"response": <value-returned-by-chaincode>
}
Besides, you may implement your chaincode to return the following object:
{
"status": <number>,
"response": <object-string-or-other-value>
}
In this case Fablo REST will use the status
as HTTP status code and a response
as a response
inside the response
body.
In case of errors along with appropriate HTTP response code, Fablo REST returns the following
body: { "message": "<error-message>" }
. The error message may be provided by Fablo REST or just passed from Fabric CA
or other nodes in the network.
See more usage examples in our E2E tests.