diff --git a/client/rest/cmd.go b/client/rest/cmd.go deleted file mode 100644 index 721e34afc..000000000 --- a/client/rest/cmd.go +++ /dev/null @@ -1,47 +0,0 @@ -package rest - -import ( - "fmt" - "log" - "net/http" - - "github.com/gorilla/mux" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - coinrest "github.com/tendermint/basecoin/modules/coin/rest" -) - -var ServeCmd = &cobra.Command{ - Use: "serve", - Short: "Serve the light REST client for tendermint", - Long: "Access basecoin via REST", - RunE: serve, -} - -const envPortFlag = "port" - -func init() { - _ = ServeCmd.PersistentFlags().Int(envPortFlag, 8998, "the port to run the server on") -} - -const defaultAlgo = "ed25519" - -func serve(cmd *cobra.Command, args []string) error { - port := viper.GetInt(envPortFlag) - keysManager := DefaultKeysManager() - router := mux.NewRouter() - ctx := Context{ - Keys: New(keysManager, defaultAlgo), - } - if err := ctx.RegisterHandlers(router); err != nil { - return err - } - if err := coinrest.RegisterHandlers(router); err != nil { - return err - } - - addr := fmt.Sprintf(":%d", port) - log.Printf("Serving on %q", addr) - return http.ListenAndServe(addr, router) -} diff --git a/client/rest/handlers.go b/client/rest/handlers.go index 22a93cb1a..695bd6a0f 100644 --- a/client/rest/handlers.go +++ b/client/rest/handlers.go @@ -21,6 +21,10 @@ func DefaultKeysManager() keys.Manager { return keysutils.GetKeyManager() } +func NewDefaultKeysManager(algo string) *Keys { + return New(DefaultKeysManager(), algo) +} + func New(manager keys.Manager, algo string) *Keys { return &Keys{ algo: algo, @@ -121,26 +125,6 @@ func (k *Keys) DeleteKey(w http.ResponseWriter, r *http.Request) { common.WriteSuccess(w, resp) } -func (k *Keys) Register(r *mux.Router) { - r.HandleFunc("/keys", k.GenerateKey).Methods("POST") - r.HandleFunc("/keys", k.ListKeys).Methods("GET") - r.HandleFunc("/keys/{name}", k.GetKey).Methods("GET") - r.HandleFunc("/keys/{name}", k.UpdateKey).Methods("POST", "PUT") - r.HandleFunc("/keys/{name}", k.DeleteKey).Methods("DELETE") -} - -type Context struct { - Keys *Keys -} - -func (ctx *Context) RegisterHandlers(r *mux.Router) error { - ctx.Keys.Register(r) - r.HandleFunc("/sign", doSign).Methods("POST") - r.HandleFunc("/tx", doPostTx).Methods("POST") - - return nil -} - func doPostTx(w http.ResponseWriter, r *http.Request) { tx := new(basecoin.Tx) if err := common.ParseRequestAndValidateJSON(r, tx); err != nil { @@ -170,3 +154,38 @@ func doSign(w http.ResponseWriter, r *http.Request) { } common.WriteSuccess(w, tx) } + +// mux.Router registrars + +// RegisterPostTx is a mux.Router handler that exposes POST +// method access to post a transaction to the blockchain. +func RegisterPostTx(r *mux.Router) error { + r.HandleFunc("/tx", doPostTx).Methods("POST") + return nil +} + +// RegisterAllCRUD is a convenience method to register all +// CRUD for keys to allow access by methods and routes: +// POST: /keys +// GET: /keys +// GET: /keys/{name} +// POST, PUT: /keys/{name} +// DELETE: /keys/{name} +func (k *Keys) RegisterAllCRUD(r *mux.Router) error { + r.HandleFunc("/keys", k.GenerateKey).Methods("POST") + r.HandleFunc("/keys", k.ListKeys).Methods("GET") + r.HandleFunc("/keys/{name}", k.GetKey).Methods("GET") + r.HandleFunc("/keys/{name}", k.UpdateKey).Methods("POST", "PUT") + r.HandleFunc("/keys/{name}", k.DeleteKey).Methods("DELETE") + + return nil +} + +// RegisterSignTx is a mux.Router handler that +// exposes POST method access to sign a transaction. +func RegisterSignTx(r *mux.Router) error { + r.HandleFunc("/sign", doSign).Methods("POST") + return nil +} + +// End of mux.Router registrars diff --git a/cmd/baseserver/main.go b/cmd/baseserver/main.go index b15603cde..27cb14b8c 100644 --- a/cmd/baseserver/main.go +++ b/cmd/baseserver/main.go @@ -1,13 +1,18 @@ package main import ( + "fmt" "log" + "net/http" "os" + "github.com/gorilla/mux" "github.com/spf13/cobra" + "github.com/spf13/viper" "github.com/tendermint/basecoin/client/commands" rest "github.com/tendermint/basecoin/client/rest" + coinrest "github.com/tendermint/basecoin/modules/coin/rest" "github.com/tendermint/tmlibs/cli" ) @@ -17,12 +22,59 @@ var srvCli = &cobra.Command{ Long: `Baseserver presents a nice (not raw hex) interface to the basecoin blockchain structure.`, } +var serveCmd = &cobra.Command{ + Use: "serve", + Short: "Serve the light REST client for tendermint", + Long: "Access basecoin via REST", + RunE: serve, +} + +const ( + envPortFlag = "port" + defaultAlgo = "ed25519" +) + +func init() { + _ = serveCmd.PersistentFlags().Int(envPortFlag, 8998, "the port to run the server on") +} + +func serve(cmd *cobra.Command, args []string) error { + router := mux.NewRouter() + + routeRegistrars := []func(*mux.Router) error{ + // rest.Keys handlers + rest.NewDefaultKeysManager(defaultAlgo).RegisterAllCRUD, + + // Coin send handler + coinrest.RegisterCoinSend, + // Coin query account handler + coinrest.RegisterQueryAccount, + + // Basecoin sign transactions handler + rest.RegisterSignTx, + // Basecoin post transaction handler + rest.RegisterPostTx, + } + + for _, routeRegistrar := range routeRegistrars { + if err := routeRegistrar(router); err != nil { + log.Fatal(err) + } + } + + port := viper.GetInt(envPortFlag) + addr := fmt.Sprintf(":%d", port) + + log.Printf("Serving on %q", addr) + return http.ListenAndServe(addr, router) +} + func main() { commands.AddBasicFlags(srvCli) srvCli.AddCommand( commands.InitCmd, - rest.ServeCmd, + serveCmd, ) // TODO: Decide whether to use $HOME/.basecli for compatibility diff --git a/modules/coin/rest/handlers.go b/modules/coin/rest/handlers.go index fbfed54c4..60f5d7b2d 100644 --- a/modules/coin/rest/handlers.go +++ b/modules/coin/rest/handlers.go @@ -34,12 +34,6 @@ type SendInput struct { Amount coin.Coins `json:"amount"` } -func RegisterHandlers(r *mux.Router) error { - r.HandleFunc("/build/send", doSend).Methods("POST") - r.HandleFunc("/query/account/{signature}", doQueryAccount).Methods("GET") - return nil -} - // doQueryAccount is the HTTP handlerfunc to query an account // It expects a query string with func doQueryAccount(w http.ResponseWriter, r *http.Request) { @@ -121,3 +115,38 @@ func doSend(w http.ResponseWriter, r *http.Request) { tx := PrepareSendTx(si) common.WriteSuccess(w, tx) } + +// mux.Router registrars + +// RegisterCoinSend is a mux.Router handler that exposes +// POST method access on route /build/send to create a +// transaction for sending money from one account to another. +func RegisterCoinSend(r *mux.Router) error { + r.HandleFunc("/build/send", doSend).Methods("POST") + return nil +} + +// RegisterQueryAccount is a mux.Router handler that exposes GET +// method access on route /query/account/{signature} to query accounts +func RegisterQueryAccount(r *mux.Router) error { + r.HandleFunc("/query/account/{signature}", doQueryAccount).Methods("GET") + return nil +} + +// RegisterAll is a convenience function to +// register all the handlers in this package. +func RegisterAll(r *mux.Router) error { + funcs := []func(*mux.Router) error{ + RegisterCoinSend, + RegisterQueryAccount, + } + + for _, fn := range funcs { + if err := fn(r); err != nil { + return err + } + } + return nil +} + +// End of mux.Router registrars