Queries Tutorial using the Composer Query language and REST APIs

In this tutorial, we will build on the developer tutorial, extending it to demonstrate queries. The native query language can filter results returned using criteria and can be invoked in transactions to perform operations, such as updating or removing assets on result sets.

Queries are defined in a query file (.qry) in the parent directory of the business network definition. Queries contain a WHERE clause, which defines the criteria by which assets or participants are selected.

This tutorial uses the tutorial-network business network developed and deployed in the Developer-Tutorial.

Update transaction logic to use queries and events

Now that the domain model has been updated, we can write the additional business logic that gets executed when a transaction is submitted for processing. In this tutorial we have added events and queries to the business logic below.

The first function tradeCommodity will change the owner property on a commodity (with a new owner Participant) on an incoming Trade transaction and emit a Notification event to that effect. It then persists the modified Commodity back into the asset registry which is used to store Commodity instances.

The second function calls a named query 'selectCommoditiesWithHighQuantity' (defined in queries.qry) which will return all Commodity asset records that have a quantity > 60 ; emit an event ; and remove the Commodity from the AssetRegistry.

Step Two: Create a query definition file

The queries used by the Transaction Processor logic are defined in a file which must be called queries.qry. Each query entry defines the resources and criteria against which the query is executed.

In the tutorial-network directory, create a new file called queries.qry.

Step Four: Deploy the updated business network definition

We need to deploy the modified network to become the latest edition on the blockchain! We are using the newly created archive business network archive file to update the existing deployed business network; this is the same business network name, that we used during the Developer Tutorial.

Switch to the terminal, change directory to the folder containing the tutorial-network.bna.

Step Five: Regenerate the REST APIs for the updated Business Network

We will now integrate the newly updated business network with queries added, and expose the REST APIs for this business network.

Using the command line, navigate to the tutorial-network directory.

Use the following command to launch the REST server:

composer-rest-server

Enter admin@tutorial-network as the card name.

Select never use namespaces when asked whether to use namespaces in the generated API.

Select No when asked whether to secure the generated API.

Select Yes when asked whether to enable event publication.

Select No when asked whether to enable TLS security.

Step Six: Test the REST APIs and create some data

Open a web browser and navigate to http://localhost:3000/explorer . You should see the LoopBack API Explorer, allowing you to inspect and test the generated REST API.

We should be able to see that the REST Endpoint called 'Query' has been added and, upon expanding, reveals the list of REST Query operations defined in the business network tutorial-network

Before we proceed, we need to create some data, to demonstrate queries adequately. Using the sample JSON data provided, create 3 Traders (Participants)and some more Commodities (Assets) using the REST APIs.

First, click on 'Trader' in the REST Explorer, then click on the 'POST' method on /Trader, then scroll down to the Parameter section - create the following Trader instances, in turn:

Now that we have some Assets and Participants, we can test out some queries using the generated Query REST operations.

Perform a simple REST query

Now that we have assets and participants, we can try out some queries.

The simplest REST query we can try out first is our named query selectCommodities.

Expand the 'Query' REST Endpoint and you will see the named queries we defined in our model.

These queries are now exposed as REST queries and for which a /GET operation is generated, Note that the description of the query (that we defined in our model definition) is shown on the right hand side.

Expand the selectCommodities query.

Click the 'Try it Out' button.

It will return all existing Commodities - there should be 2 assets returned.

Perform Filtered REST Queries

Let's select all Commodities by their Exchange - for example 'EURONEXT' main exchange.

Expand query Endpoint 'selectCommoditiesByExchange' and scroll to the 'Parameters' section.

Enter 'EURONEXT' in the 'Exchange' parameter.

Click 'Try it Out'.

The results reveal that only those Commodities with an Exchange of 'EURONEXT' are shown in the response body

Perform Transaction update using results from named Query

Finally, you will recall we had defined a simple query that filters Commodities with a Quantity greater than 60 in our query file. Queries are very powerful, when used in transaction functions, as using queries allows transaction logic to set up the set of assets or participants to perform updates on, or for creating remove actions for example.

We use the selectCommoditiesWithHighQuantity query in the removeHighQuantityCommodities transaction. If you execute this /GET operation in the REST Explorer, you'll see it selects only those assets greater than 60 in quantity.

Now let's use the query to perform a removal of high quantity Commodities.

First check for yourself how many Commodities are present (use the 'Commodity' /GET operation) and you should see at least two Commodities, one of which (Cocoa) has a quantity > 60.

Let's check out the actual query, by clicking on the REST Endpoint /selectCommoditiesWithHighQuantity and click /GET then scroll down to 'Try it Out' - there should be one Commodity that meets the criteria.

OK. Now let's execute a REST transaction, that uses our 'High Quantity' query definition to decide which Commodities to remove.

Click on the RemoveHighQuantityCommodities REST Endpoint to reveal the /POST operation for same.

Click on POST, scroll down to the Parameter section and click 'Try it Out' - note: you do not have to enter any data in the 'data' section.

Scroll down and you should see a transactionId which represents the 'remove' invocation (itself a blockchain transaction) inside of the transaction processor function and which will update the world state - the Response Code should be 200

Finally, let's verify our Commodities status. Return to the 'Commodity' REST Operations and once again perform a /GET operation....'Try it Out'.

The results should show that the Commodity asset 'Cocoa' has now gone, ie only those Commodity assets with a quantity <= 60 still remain, ie asset 'Corn' in our example. The named query fed the transaction update (to remove high quantity Commodities) and which was executed in business logic.

Congratulations!

Well done, you've now completed this tutorial and we hope you now have a much better idea of the power of queries in Composer. You can start creating/building your own queries (or modifying the existing queries and adding associated data to this business network - note: you would need to re-deploy any query changes) to try out!