At some point you may want to create a front-end to your application and interact with it by sending HTTP requests. In part 2 we’ve seen that sending requests to /abci_query
is one way of getting data from your app. This works well for testing and certain specific usecases, but for a production application you may want to create a clean API for yourself and other users. This API should probably have short endpoints (without implementation details, like abci
) and respond differently to HTTP verbs like GET and POST. You may also want to have some requst processing logic that handles basic checks and data transformation. Luckily, Cosmos SDK provides just that.
Let’s create a server that handles GET
requests to /blog/posts
endpoint by returning a list of posts.
x/blog/client/rest/rest.go
import (
// Existing imports...
"fmt"
"net/http"
"github.com/cosmos/cosmos-sdk/types/rest"
)
In this file you should see func RegisterRoutes
used for registering HTTP endpoints and handler functions.
Add the following line to register our first route:
r.HandleFunc("/blog/posts", listPostsHandler(cliCtx, "blog")).Methods("GET")
Now let’s define listPostsHandler
in the same package:
func listPostsHandler(cliCtx context.CLIContext, storeName string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/list-posts", storeName), nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
return
}
rest.PostProcessResponse(w, cliCtx, res)
}
}
As many handler functions in Cosmos apps listPostsHandler
takes context, which contains meta information about the app and its environment, as a first argument. We’re also passing storeName
, which in our case is "blog"
.
Similarly to the CLI handler the function runs QueryWithData
with a custom/blog/list-posts
ABCI query. The []byte
return value then gets unmarshalled into JSON and returned to the handler.
To build your app and launch servers, run:
starport serve
Alternatively, follow instructions in Part 1 to recompile and relaunch your app and add some test posts to the store. Make sure blogcli q blog list-posts
returns a list of posts.
To launch our HTTP server run the following command in a different terminal window:
blogcli rest-server
You should see server logs streaming in the terminal:
I[2020-06-07|11:19:14.921] Starting application REST service (chain-id: "blog")... module=rest-server
I[2020-06-07|11:19:14.921] Starting RPC HTTP server on 127.0.0.1:1317 module=rest-server
As we can see by default the server runs on 1317
port. Let’s make a request to our handler: