获取 cli
========
cli 开源在 [github](https://github.com/mkideal/cli) 上,欢迎大家前去 star :-)
使用go get获取
```shell
go get github.com/mkideal/cli
```
[上一篇](http://studygolang.com/topics/1520)介绍了`Command`和`Context`对象,以及构建多层子命令的方法.本片将介绍一个构建http服务的栗子。本篇示例代码由 [**goplus**](https://github.com/mkideal/goplus) 生成
```shell
goplus new -t http httpd
```
##示例代码
```go
package main
import (
"fmt"
"os"
"github.com/mkideal/cli"
)
func main() {
if err := cli.Root(root,
cli.Tree(help),
cli.Tree(daemon),
cli.Tree(api,
cli.Tree(ping),
),
).Run(os.Args[1:]); err != nil {
fmt.Println(err)
}
}
//------
// root
//------
var root = &cli.Command{
Fn: func(ctx *cli.Context) error {
ctx.WriteUsage()
return nil
},
}
//------
// help
//------
var help = &cli.Command{
Name: "help",
Desc: "display help",
CanSubRoute: true,
HTTPRouters: []string{"/v1/help"},
HTTPMethods: []string{"GET"},
Fn: cli.HelpCommandFn,
}
//--------
// daemon
//--------
type daemonT struct {
cli.Helper
Port uint16 `cli:"p,port" usage:"http port" dft:"8080"`
}
func (t *daemonT) Validate(ctx *cli.Context) error {
if t.Port == 0 {
return fmt.Errorf("please don't use 0 as http port")
}
return nil
}
var daemon = &cli.Command{
Name: "daemon",
Desc: "startup app as daemon",
Argv: func() interface{} { return new(daemonT) },
Fn: func(ctx *cli.Context) error {
argv := ctx.Argv().(*daemonT)
if argv.Help {
ctx.WriteUsage()
return nil
}
//NOTE: remove following line will disable debug mode
cli.EnableDebug()
addr := fmt.Sprintf(":%d", argv.Port)
cli.Debugf("http addr: %s", addr)
r := ctx.Command().Root()
if err := r.RegisterHTTP(ctx); err != nil {
return err
}
return r.ListenAndServeHTTP(addr)
},
}
//-----
// api
//-----
var api = &cli.Command{
Name: "api",
Desc: "display all api",
Fn: func(ctx *cli.Context) error {
ctx.String("Commands:\n")
ctx.String(" ping\n")
return nil
},
}
//------
// ping
//------
var ping = &cli.Command{
Name: "ping",
Desc: "ping server",
Fn: func(ctx *cli.Context) error {
ctx.String("pong\n")
return nil
},
}
```
## daemon命令
示例中,负责启动`http`服务的是`daemon`命令。注意代码的77~81这5行:
```go
r := ctx.Command().Root()
if err := r.RegisterHTTP(ctx); err != nil {
return err
}
return r.ListenAndServeHTTP(addr)
```
这里通过`ctx.Command().Root()`获取到根命令,然后调用根命令的`RegisterHTTP`方法。这个方法主要是注册各个命令的自定义路由.
在上面这个示例中只为`help`命令指定了自定义的路由
```go
HTTPRouters: []string{"/v1/help"},
```
## 别的命令
示例中别的命令的实现都非常简单,比如`api`及其子命令`ping`,都只是输出一个字符串.
## 启动服务
cd到代码目录,编译然后运行
```shell
$> go build -o httpd
$> ./httpd daemon -p 8080
```
然后就可以在浏览器上访问
http:127.0.0.1:8080/api/ping
或者使用curl
```shell
curl http:127.0.0.1:8080/api/ping
```
如果你在本直接运行
```shell
./httpd api ping
```
你会发现这和使用http访问得到的输出是一样的。
由于`help`指令置顶了自定义路由`/v1/help`,所以处理可以通过标准路由
```
http://127.0.0.1:8080/help
```
访问外,还可以通过自定义路由访问
```
http://127.0.0.1:8080/v1/help
```
## 结语
使用`cli`创建`http`服务就这么简单.只需要调用根命令的`ListenAndServeHTTP`方法就可以了,当然如果你要是使用自定义路由,这需要调用根命令的`RegisterHTTP`方法。启动`http`服务后,其他所有命令都可以通过`http`调用了。
在[github](https://github.com/mkideal/cli)上参看`http`的栗子.
* [HTTP](https://github.com/mkideal/cli/blob/master/examples/http/main.go)
有疑问加站长微信联系(非本文作者)