In the previous article we discovered how the select
parameter can significantly reduce the amount of transmitted data and response time.
In this article we will explain how you can significantly speed up the performance, and moreover simplify the logic of your application, by using data filtering in the request query to Tezos Explorer TzKT API. It doesn't matter what kind of application you are developing. It can be a simple baker's dashboard, a wallet or even an exchange. If you use request-level filtering, you rely on TzKT API logic, which greatly reduces the risk of errors.
# Table of contents
- ✅ Don't request the same data until it actually changes
- ✅ Request only what you actually need
- ✅ Filter data on the API, not on the client
- 🔜 Use pagination carefully
# Filter data on the Tezos API, not on the client
Each time we request an array of data from the Tezos API, we actually need a very specific small part of the data. Let's take a look at the simple example when we need just one delegator's reward payout transaction for the particular cycle. We can simply get all incoming transactions, as, unfortunately, a lot of people do: /operations/transactions?target={address}&limit=10000
NOTE
If you use the limit=10000
(current maximum for the TzKT API) in your application, it is most likely your application needs optimization.
And we've got 117 transactions. That's definitely not what we were looking for. Let's get it optimized!
First, let's exclude failed
, backtracked
and skipped
transactions, leaving only applied
: ...&status=applied
We've got 113 transactions, a little bit better, but that's still not enough.
Obviously, in the vast majority of cases, we only need to look into a specific period of time. Usually it is enough to take a selection only for the previous Tezos block or cycle. In our case we need only one cycle transactions ...&level.ge={cycleStart}&level.lt={nextCycleStart}
NOTE
As you can see, TzKT Tezos API allows you to specify various parameter modes such as .gt
(greater than), .ge
(greater or equal), .lt
(less than) and .le
(less or equal) for more precise filtering.
Ha! Just 3 transactions! Seems like that's almost what we were looking for!
All we need now is to realize that reward payouts have specific amount, around its average value (in our example, between 0.1 tez and 1 tez), so we can filter out unwanted transactions by the amount
field ...&amount.gt=100000&amount.le=1000000
NOTE
Please, note, all amounts in TzKT API are in microtez
Now we see only one transaction.
And finally, let's use what we learned from the previous article and add ?select
to get only the fields we really need: ...&select=timestamp,sender,amount,bakerFee
In the end, we have not only achieved a significant saving of data volume (16 KB vs. 294 B in our case) and response speed (180 ms vs. 51 ms in our case), but we have also significantly simplified the application logic and successfully delegated data filtering to the API.
NOTE
If your application requires filtering by some specific parameters, which haven't been implemented yet, just contact us, and we'll do our best to fit your needs!
# Advanced request filtering
That's the beginning of what we want to show! TzKT API provides much more options for data filtering. Let's dig a little deeper.
# Basic modes
In addition to the desctibed above .gt
, .ge
, .lt
and .le
basic modes there are aslo .eq
and .ne
modes, Let's say we need all unsuccessfull operations. For that purpose we can use not equal filtering mode param.ne=123
. It helps us to exclude all entities with a particular value. And our request will look like ..status.ne=applied
NOTE
The not equal filtering mode is suitable for both numerical and string values.
# Filter by list
Sometimes we need to filter data by a list of allowed values (for example list of addresses of the wallet), we can use in list param.in=12,34,56
and not in list param.ni=12,34,56
options to get all required data by just one request:/transactions?sender.in={firstAddress},{secondAddress}
# Filter by another field
Also, we may need to filter data not by the particular value(s), but by its "nature". For example, what if we want to get all operations of baker registration/reactivation? In other words, we need to get the Tezos delegation operations where sender
field is equal to newDelegate
field. In such cases we can use equal to another field param1.eqx=param2
and not equal to another field param1.nex=param2
filtering modes: /delegations?newDelegate.eqx=sender
. Another example is requesting all loop-transfers: /transactions?sender.eqx=receiver
.
# Check on null
If it's suitable, don't hesitate to use the null
check parameter in your requests. Let's consider we need only delegation cancelation operations: /delegations?prevDelegate.null=false&newDelegate.null=true
NOTE
&newDelegate.null=true
can be simplified/shortened to &newDelegate.null
, without =true
.
# Wildcard pattern matching
TzKT API allows you to use wildcard pattern matching on transaction parameters. This is helpful when you need to filter smart contract calls. For example, if we need to get a particular token's transfers the .as
wildcard pattern matching comes to the aid: /transactions?...parameters.as=*"entrypoint":"transfer"*
.
NOTE
And of course we can inverse the request by the opposite unlike filter mode .un
: ...parameters.un=*"entrypoint":"transfer"*
# Dealing with batch and internal Tezos operations
Often filtration is not required at all, and we can get the operation we need just by its hash: /operations/{hash}
If it is a batch operation, you can use the counter
of a specific operation within the batch to avoid requesting all operations when you need only one: /operations/{hash}/{counter}
If the operation contains an internal operation, you can get internal operation by its counter
and nonce
: /operations/{hash}/{counter}/{nonce}
# Conclusion
To sum up, we would like to say that data filtering on the API side has a number of undeniable advantages, such as reduced load on the client application and significantly higher download speed due to a smaller amount of data. We will be very glad if you will use the maximum features of the TzKT API because that's what it was created for.
# What's next?
This is the third article of series "Tezos Explorer API Best Practices". In the next article we'll talk about pagination in API requests.
Cheers!