diff --git a/asset-transfer-basic/rest-api-typescript/README.md b/asset-transfer-basic/rest-api-typescript/README.md index 5bcb1f17..e2314dc5 100644 --- a/asset-transfer-basic/rest-api-typescript/README.md +++ b/asset-transfer-basic/rest-api-typescript/README.md @@ -1,29 +1,94 @@ # Asset Transfer REST API Sample -Prototype sample REST server to demonstrate good Fabric Node SDK practices +Sample REST server to demonstrate good Fabric Node SDK practices. -The primary aim of this sample is to show how to write a long running client application using the Fabric Node SDK +The REST API is only intended to work with the [basic asset transfer example](https://github.com/hyperledger/fabric-samples/tree/main/asset-transfer-basic). -The REST API is intended to work with the [basic asset transfer example](https://github.com/hyperledger/fabric-samples/tree/main/asset-transfer-basic) - -To install the basic asset transfer chaincode on a local Fabric network, follow the [Using the Fabric test network](https://hyperledger-fabric.readthedocs.io/en/release-2.4/test_network.html) tutorial +To install the basic asset transfer chaincode on a local Fabric network, follow the [Using the Fabric test network](https://hyperledger-fabric.readthedocs.io/en/release-2.4/test_network.html) tutorial. ## Overview -The sample creates two long lived connections to a Fabric network in order to submit and evaluate transactions using two different identities +The primary aim of this sample is to show how to write a long running client application using the Fabric Node SDK. +In particular, client applications **should not** create new connections for every transaction. -To ensure requests respond quickly enough to avoid timeouts, all submit transactions are queued for processing and will be retried if they fail +The sample also demonstrates possible error handling approaches and handles multiple requests from multiple identities. -Submit transactions are retried if they fail with any error, except for errors from the smart contract, or duplicate transaction errors +The following sections describe the structure of the sample, or [skip to the usage section](#usage) to try it out first. + +### Fabric network connections + +The sample creates two long lived connections to a Fabric network in order to submit and evaluate transactions using two different identities. + +The connections are made when the application starts and are retained for the life of the REST server. + +Related files: + +- [src/fabric.ts](src/fabric.ts) + All the sample code which interacts with the Fabric network via the Fabric SDK. + For example, the `createGateway` function which connects to the Fabric network. +- [src/index.ts](src/index.ts) + The primary entry point for the sample. + Connects to the Fabric network and starts the REST server. + +### Error handling + +In this sample submit transactions are retried if they fail with any error, **except** for errors from the smart contract, or duplicate transaction errors. Alternatively you might prefer to modify the sample to only retry transactions which fail with specific errors instead, for example: + - MVCC_READ_CONFLICT - PHANTOM_READ_CONFLICT - ENDORSEMENT_POLICY_FAILURE - CHAINCODE_VERSION_CONFLICT - EXPIRED_CHAINCODE -See [src/index.ts](src/index.ts) for a description of the sample code structure, and [src/config.ts](src/config.ts) for details of configuring the sample using environment variables. +Related files: +- [src/errors.ts](src/errors.ts) + All the Fabric transaction error handling and retry logic. + +### Asset REST API + +While the basic asset transfer chaincode maps well to an `/api/assets` REST API, response times when submitting transactions to a Fabric network are problematic for REST APIs. + +A common approach to handle long running operations in REST APIs is to immediately return `202 ACCEPTED`, with the operation being represented by another resource, namely a `job` in this sample. + +Jobs are used for submitting transactions to create, update, delete, or transfer an asset. +The `202 ACCEPTED` response includes a `jobId` which can be used with the `/api/jobs` endpoint to get the results of the create, update, delete, or transfer request. + +Jobs are not used to get assets, because evaluating transactions is typically much faster. + +Related files: +- [src/asset.router.ts](src/asset.router.ts) + Defines the main `/api/assets` endpoint. +- [src/fabric.ts](src/fabric.ts) + All the sample code which interacts with the Fabric network via the Fabric SDK. +- [src/jobs.router.ts](src/jobs.router.ts) + Defines the `/api/jobs` endpoint for getting job status. +- [src/jobs.ts](src/jobs.ts) + Job queue implementation details. +- [src/transactions.router.ts]() + Defines the `/api/transactions` endpoint for getting transaction status. + +**Note:** If you are not specifically interested in REST APIs, you should only need to look at the files in the [Fabric network connections](#fabric-network-connections) and [Error handling](#error-handling) sections above. + +### REST server + +The remaining sample files are related to the REST server aspects of the sample, rather than Fabric itself: + +- [src/auth.ts](src/auth.ts) + Basic API key authentication strategy used for the sample. +- [src/config.ts](src/config.ts) + Descriptions of all the available configuration environment variables. +- [src/jobs.ts](src/jobs.ts) + Job queue implementation details. +- [src/logger.ts](src/logger.ts) + Logging implementation details. +- [src/redis.ts](src/redis.ts) + Redis implementation details. +- [src/server.ts](src/server.ts) + Express server implementation details. + +**Note:** If you are not specifically interested in REST APIs, you should only need to look at the files in the [Fabric network connections](#fabric-network-connections) and [Error handling](#error-handling) sections above. ## Usage @@ -51,6 +116,8 @@ Create a `.env` file to configure the server for the test network (make sure TES TEST_NETWORK_HOME=$HOME/fabric-samples/test-network npm run generateEnv ``` +**Note:** see [src/config.ts](src/config.ts) for details of configuring the sample + Start a Redis server (Redis is used to store the queue of submit transactions) ```shell @@ -79,13 +146,15 @@ Create a `.env` file to configure the server for the test network (make sure `TE TEST_NETWORK_HOME=$HOME/fabric-samples/test-network AS_LOCAL_HOST=false npm run generateEnv ``` +**Note:** see [src/config.ts](src/config.ts) for details of configuring the sample + Start the sample REST server and Redis server ```shell docker-compose up -d ``` -## REST API +## REST API demo If everything went well, you can now open a new terminal and try out some basic asset transfer REST calls! diff --git a/asset-transfer-basic/rest-api-typescript/src/errors.ts b/asset-transfer-basic/rest-api-typescript/src/errors.ts index 66272e87..010db75f 100644 --- a/asset-transfer-basic/rest-api-typescript/src/errors.ts +++ b/asset-transfer-basic/rest-api-typescript/src/errors.ts @@ -164,7 +164,6 @@ export const isDuplicateTransactionError = (err: unknown): boolean => { * "Asset %s already exists" */ const matchAssetAlreadyExistsMessage = (message: string): string | null => { - // const assetAlreadyExistsRegex = /([tT]he )?[aA]sset \w* already exists/g; const assetAlreadyExistsMatch = message.match(assetAlreadyExistsRegex); logger.debug( diff --git a/asset-transfer-basic/rest-api-typescript/src/index.ts b/asset-transfer-basic/rest-api-typescript/src/index.ts index c9a08574..75c0d66c 100644 --- a/asset-transfer-basic/rest-api-typescript/src/index.ts +++ b/asset-transfer-basic/rest-api-typescript/src/index.ts @@ -4,32 +4,6 @@ * This is the main entrypoint for the sample REST server, which is responsible * for connecting to the Fabric network and setting up a job queue for * processing submit transactions - * - * You can find more details related to the Fabric aspects of the sample in the - * following files: - * - * - errors.ts - * Fabric transaction error handling and retry logic - * - fabric.ts - * all the sample code which interacts with the Fabric SDK - * - * The remaining files are related to the REST server aspects of the sample, - * rather than Fabric itself: - * - * - *.router.ts - * details of the REST endpoints provided by the sample - * - auth.ts - * basic API key authentication strategy used for the sample - * - config.ts - * descriptions of all the available configuration environment variables - * - jobs.ts - * job queue implementation details - * - logger.ts - * logging implementation details - * - redis.ts - * redis implementation details - * - server.ts - * express server implementation details */ import * as config from './config';