A Querier
designates a function that processes queries
. querier
s are specific to the module in which they are defined, and only process queries
defined within said module. They are called from baseapp
's Query
method. {synopsis}
- Module Manager {prereq}
- Messages and Queries {prereq}
The querier
type defined in the Cosmos SDK specifies the typical structure of a querier
function:
Let us break it down:
- The
path
is an array ofstring
s that contains the type of the query, and that can also containquery
arguments. Seequeries
for more information. - The
req
itself is primarily used to retrieve arguments if they are too large to fit in thepath
. This is done using theData
field ofreq
. - The
Context
contains all the necessary information needed to process thequery
, as well as a cache-wrapped copy of the latest state. It is primarily used by thekeeper
to access the state. - The result
res
returned tobaseapp
, marhsalled using the application'scodec
.
Module querier
s are typically implemented in a ./internal/keeper/querier.go
file inside the module's folder. The module manager is used to add the module's querier
s to the application's queryRouter
via the NewQuerier()
method. Typically, the manager's NewQuerier()
method simply calls a NewQuerier()
method defined in keeper/querier.go
, which looks like the following:
func NewQuerier(keeper Keeper) sdk.Querier {
return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) {
switch path[0] {
case QueryType1:
return queryType1(ctx, path[1:], req, keeper)
case QueryType2:
return queryType2(ctx, path[1:], req, keeper)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0])
}
}
}
This simple switch returns a querier
function specific to the type of the received query
. At this point of the query lifecycle, the first element of the path
(path[0]
) contains the type of the query. The following elements are either empty or contain arguments needed to process the query.
The querier
functions themselves are pretty straighforward. They generally fetch a value or values from the state using the keeper
. Then, they marshall the value(s) using the codec
and return the []byte
obtained as result.
For a deeper look at querier
s, see this example implementation of a querier
function from the nameservice tutorial.
Learn about BeginBlocker
and EndBlocker
{hide}