Skip to content

teamlint/baron

Folders and files

NameName
Last commit message
Last commit date

Latest commit

05d1c7e · Jan 26, 2021
Jan 13, 2021
Oct 29, 2020
Jan 14, 2021
Nov 3, 2020
Nov 6, 2020
Jan 13, 2021
Jan 14, 2021
Nov 6, 2020
Jan 26, 2021
Oct 29, 2020
Oct 30, 2020
Oct 14, 2020
Oct 28, 2020
Nov 10, 2020
Jan 11, 2021
Sep 6, 2020
Nov 3, 2020
Oct 29, 2020
Oct 28, 2020

Repository files navigation

Baron

micro service development framework

Baron 根据 proto 文件快速生成 go-kit 微服务框架, 让您专注于业务功能开发😉

功能特性

  • Service 差异化代码生成

  • Google 官方新版 proton-gen-go 代码生成

  • Google 官方新版 protoc-gen-go-grpc 代码生成

  • gRPC 传输协议支持

  • HTTP 传输协议支持

  • NATS 传输协议支持

  • Proto3 optional 字段属性支持

  • google/protobuf/any.proto 字段类型支持

  • google/protobuf/empty.proto 字段类型支持

  • google/protobuf/timestamp.proto 字段类型支持

  • google/protobuf/duration.proto 字段类型支持

  • google/protobuf/wrappers.proto 字段类型支持

  • google/protobuf/struct.proto 字段类型支持

  • 文档生成

  • gRPC Stream

  • server 初始化中间件

  • 使用 zerolog 替换 logrus

  • HTTP 错误标准化

  • CLI 子命令

安装

安装 protoc 工具

下载 并安装 protocol buffer 编译工具

安装 protoc 插件

$ export GO111MODULE=on  # Enable module mode
$ go get google.golang.org/protobuf/cmd/protoc-gen-go \
         google.golang.org/grpc/cmd/protoc-gen-go-grpc

安装 baron 命令行

$ go get -u -d github.com/teamlint/baron
cd $GOPATH/src/github.com/teamlint/baron
task install

注: 使用task作为编译部署工具, 详细官方文档

命令行

简介

  • 命令行名称: baron

  • 命令行帮助: baron -h

    $ baron -h
    baron (version: v0.2.5 version date: 2020-11-05T15:36:20+08:00)
    
    Usage: baron [options] <protofile>...
    
    Generates baron(go-kit) services using proto3 and gRPC definitions.
    
    Options:
      -c, --client             Generate NAME-service client
      -h, --help               Print usage
      -s, --start              Output a 'start.proto' protobuf file in ./
      -d, --svcdef             Print service definition
      -o, --svcout string      Go package path where the generated Go service will be written. Trailing slash will create a NAME-service directory
      -t, --transport string   Service transport protocol: [grpc|nats] (default "all")
      -v, --verbose            Verbose output
      -V, --version            Print version

服务端使用

1.初始化服务定义

命令名称: baron --start <pkgname> [outdir]

  • 省略pkgname参数则使用start作为默认包名, 并生成 start.proto文件
  • 省略outdir参数则在当前目录生成 <pkgname>.proto文件
$ baron --start foo
INFO[0000] A "start" protobuf file named 'foo.proto' has been created in the
current directory. You can generate a service based on this new protobuf file
at any time using the following command:

    baron foo.proto

If you want to generate a protofile with a different name, use the
'--start' option with the name of your choice after '--start'. For
example, to generate a 'foo.proto', use the following command:

    baron --start foo

2.编写服务定义

打开 <pkgname>.proto文件, 使用 proto3 语法编写服务相关定义

3.生成服务基础框架代码

$ baron foo.proto

查看生成文件

$ ls
foo-service     foo.pb.baron.go foo.pb.go       foo.proto       foo_grpc.pb.go

外部引用代码生成在 [outdir]目录, 默认为当前目录, 实际开发建议使用独立目录

所有服务端代码放置在 -service 子目录

查看服务端代码结构

$ tree -L 3 ./foo-service
./foo-service
├── cmd
│   └── foo
│       └── main.go
├── server
│   └── server.go
└── service
    ├── hooks.go
    ├── middlewares.go
    └── service.go

4 directories, 5 files

4.编写业务逻辑代码

打开service.go文件编写业务逻辑代码

注: 服务定义修改后, 使用baron foo.proto重新生成代码即可, 会对新老代码进行差异化修改

客户端使用

1.添加引用包

import pb "<gomod>/<proto-name>" // [outdir] 目录下所有代码

2.调用服务

GRPC 客户端调用
// Baron GRPC Client
log.Println("[GRPC.Start]")
conn, err := grpc.Dial(
  grpcAddr,
  grpc.WithInsecure(),
  grpc.WithBlock(),
)
if err != nil {
  log.Fatal(err)
}
defer conn.Close()
baronGRPCClient, err := pb.NewGRPCClient(conn)
if err != nil {
  log.Fatal(err)
}

// GRPC.Start.Status
{
  ctx := context.Background()
  var in pb.StatusRequest
  out, err := baronGRPCClient.Status(ctx, &in)
  if err != nil {
    log.Fatalf("[Baron.GRPCClient] Start.Status err=%v\n", err)
  }
  log.Printf("[Baron.GRPCClient] Start.Status result=%+v\n", *out)
  log.Println()
}
HTTP 客户端调用
// Baron HTTP Client
log.Println("[HTTP][Start]")

// HTTP.Start.Status
{
  ctx := context.Background()
  var in pb.StatusRequest
  baronHTTPClient, err := pb.NewHTTPClient(httpAddr)
  if err != nil {
    log.Fatal(err)
  }
  out, err := baronHTTPClient.Status(ctx, &in)
  if err != nil {
    log.Fatalf("[Baron.HTTPClient] Start.Status err=%v\n", err)
  }
  log.Printf("[Baron.HTTPClient] Start.Status result=%+v\n", *out)
  log.Println()
}
NATS 客户端调用
// Baron NATS Client
log.Println("[NATS.Start]")
nc, err := nats.Connect(natsAddr)
if err != nil {
  log.Fatal(err)
}
defer nc.Close()
baronNATSClient, err := pb.NewNATSClient(nc)
if err != nil {
  log.Fatal(err)
}

// NATS.Start.Status
{
  ctx := context.Background()
  var in pb.StatusRequest
  out, err := baronNATSClient.Status(ctx, &in)
  if err != nil {
    log.Fatalf("[Baron.NATSClient] Start.Status err=%v\n", err)
  }
  log.Printf("[Baron.NATSClient] Start.Status result=%+v\n", *out)
  log.Println()
}

注意事项

  • HTTP 服务请求如果使用查询字符串传递复杂数据类型, 需要将字段值编码为JSON并做URL编码, 使用请求体传值可直接使用原始值

服务定义

message EchoRequest {
	google.protobuf.StringValue json_str  = 6;
}

使用 URL 查询参数传值

  • 将参数 JSON 序列化 {"value":"Hello世界"}

  • URL 编码 %7B%22value%22%3A%22Hello%E4%B8%96%E7%95%8C%22%7D

http://localhost:5050/echo?json_str=%7B%22value%22%3A%22Hello%E4%B8%96%E7%95%8C%22%7D

使用 HTTP Body 传值

{
"json_str": "Hello世界"
}

已知问题

  • google/protobuf/struct.proto 生成的字段必须设置值,设置 nil 报错

参考