# Add Your First Query
In the previous section you added a message that lets you create new games. However, other than dumping the full storage, you cannot retrieve them yet as there is no query type defined. This section fixes that. You will:
- Add a query type to retrieve a game by index.
- Add all the necessary keeper and message server functions.
- Add CLI commands.
Note that you will only create a query to retrieve a single game, not a list of games, which would also be convenient. This other query is more complex and requires pagination.
# Add a game retrieval query
With the game storage indexed by game index, it is only natural to retrieve games by index. It is time to add a query to let anyone fetch games. You are going to:
- Create the query type.
- Compile Protobuf
- Create a query server next to the keeper.
- Handle the query.
- Register the necessary elements in the module.
# The game retrieval object type and Protobuf service
These are defined together in a new file
proto/alice/checkers/v1/query.proto that you create:
Note that the
StoredGame included in the response does not need to include the
Index field as it is implicit over the request's lifecycle.
# Compile Protobuf
Since you have defined a new query type and an associated
service, you should recompile everything:
In the new
query.pg.go (opens new window), you can find
type QueryGetGameRequest struct (opens new window) and
type QueryServer interface (opens new window). Now you can use them closer to the keeper.
# New query server
Create a new file
keeper/query_server.go and take inspiration from
minimal-module-example. It needs to:
- Implement the
- Return the game if it is found.
- Return no games and no errors if it is not found.
- Return an error otherwise.
Note how the response's
Game is a pointer. This lets you define it as
nil in the case there is no game at the requested index.
With the query server defined, you now need to register it in the module.
# Register the types in the module
Now that you have message types and server, you should register the service in
module/module.go. Inspire yourself from what you find in
minimal-module-example. The lines were previously commented out:
# Add the CLI commands
At this stage, your module is able to handle queries passed to it by the app. But you are not yet able to craft such a query in the first place. When working from the command line, that crafting is handled by the CLI client. The CLI client usually tells you what queries it can create when you run
minid query --help. Go ahead and check:
You can see that
checkers is missing from the list of available commands. Fix that by entering your desired command in
module/autocli.go. Taking inspiration from
Note that the
"get-game index" is parsed out and used as the command in the
minid query checkers get-game command-line.
# Test again
Back in the minimal chain, compile to see the command that was added:
Now, you should see the
This time, adding a query did not change your genesis or storage, so you do not need to re-initialize. Start it:
Now query your previously created game:
Try to get a non-existent game:
This should return:
Confirm this returned without any error:
You have started creating the first elements of a simple checkers blockchain, one where it is possible to create, and recall, games.
Compared to earlier versions, Cosmos SDK v0.50 allows you to create modules in a more modular and concise way.
If you still want to reduce the amount of work to do, in a way reminiscent of on Rails environments, you can use Ignite CLI. This is what you can learn in the next sections, where Ignite CLI is used to quickly create a checkers blockchain at an earlier (0.45) version of the Cosmos SDK.