# Messages and Queries
Queries are the two primary objects handled by modules. Most of the core components defined in a module, like
Query services, exist to process
# Pre-requisite Readings
Msgs are objects whose end-goal is to trigger state-transitions. They are wrapped in transactions, which may contain one or more of them.
When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by
BaseApp. Then, each message contained in the transaction is extracted and routed to the appropriate module via
MsgServiceRouter so that it can be processed by the module's
Msg service. For a more detailed explanation of the lifecycle of a transaction, click here.
Starting from v0.40, defining Protobuf
Msg services is the recommended way to handle messages. A
Msg protobuf service should be created per module, typically in
tx.proto (see more info about conventions and naming). It must have an RPC service method defined for each message in the module.
See an example of a
Msg service definition from
For backwards compatibility with legacy Amino
Msg types should be used as the request parameter for
service definitions. Newer
Msg types which only support
service definitions should use the more canonical
Msg request types need to implement the
MsgRequest interface which is a simplified version of the
Msg interface described below with only
Msg services allow to specify return types as part of
Msg response using the canonical
In addition, this generates client and server code.
MsgServer interface defines the server API for the
Msg service and its implementation is described as part of the
Msg services documentation.
RegisterMsgServer method is also generated and should be used to register the module's
MsgServer implementation in
RegisterServices method from the
In order for clients (CLI and grpc-gateway) to have these URLs registered, the SDK provides the function
RegisterMsgServiceDesc(registry codectypes.InterfaceRegistry, sd *grpc.ServiceDesc) that should be called inside module's
RegisterInterfaces method, using the proto-generated
# Legacy Amino
This way of defining messages is deprecated and using
Msg services is preferred.
Msgs can be defined as protobuf messages. The messages definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said message.
Msg is typically accompanied by a standard constructor function, that is called from one of the module's interface.
messages also need to implement the [
proto.Message and contains the following methods:
Route() string: Name of the route for this message. Typically all
messages in a module have the same route, which is most often the module's name.
Type() string: Type of the message, used primarly in events. This should return a message-specific
string, typically the denomination of the message itself.
ValidateBasic() error: This method is called by
BaseAppvery early in the processing of the
DeliverTx), in order to discard obviously invalid messages.
ValidateBasicshould only include stateless checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the
amountis strictly positive for a transfer).
GetSignBytes() byte: Return the canonical byte representation of the message. Used to generate a signature.
GetSigners() AccAddress: Return the list of signers. The SDK will make sure that each
messagecontained in a transaction is signed by all the signers listed in the list returned by this method.
See an example implementation of a
message from the
query is a request for information made by end-users of applications through an interface and processed by a full-node. A
query is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via
queryrouter so that it can be processed by the module's query service (./query-services.md). For a deeper look at the lifecycle of a
query, click here.
# gRPC Queries
Starting from v0.40, the prefered way to define queries is by using Protobuf services (opens new window). A
Query service should be created per module in
query.proto. This service lists endpoints starting with
Here's an example of such a
Query service definition:
Response types implement by default
String() method of
fmt.Stringer (opens new window).
RegisterQueryServer method is also generated and should be used to register the module's query server in the
RegisterServices method from the
# Legacy Queries
Before the introduction of Protobuf and gRPC in the SDK, there was usually no specific
query object defined by module developers, contrary to
messages. Instead, the SDK took the simpler approach of using a simple
path to define each
path contains the
query type and all the arguments needed in order to process it. For most module queries, the
path should look like the following:
queryCategoryis the category of the
customfor module queries. It is used to differentiate between different kinds of queries within
queryRouteis used by
queryRouterto map the
queryto its module. Usually,
queryRouteshould be the name of the module.
queryTypeis used by the module's
querierto map the
queryto the appropriate
querier functionwithin the module.
argsare the actual arguments needed to process the
query. They are filled out by the end-user. Note that for bigger queries, you might prefer passing arguments in the
Datafield of the request
reqinstead of the
path for each
query must be defined by the module developer in the module's command-line interface file.Overall, there are 3 mains components module developers need to implement in order to make the subset of the state defined by their module queryable:
querier, to process the
queryonce it has been routed to the module.
- Query commands in the module's CLI file, where the
queryreturn types. Typically defined in a file
types/querier.go, they specify the result type of each of the module's
queries. These custom types must implement the
fmt.Stringer(opens new window).
# Store Queries
Store queries query directly for store keys. They use
clientCtx.QueryABCI(req abci.RequestQuery) to return the full
abci.ResponseQuery with inclusion Merkle proofs.
See following examples: