【Web框架】【go-zero框架】1.goctl工具

go-zero: https://github.com/zeromicro/go-zero
官方文档:https://go-zero.dev/docs/tutorials

1 关于goctl工具

官方文档中有句话触动到我了:工具大于约定和文档。
触动2:不要去控制代码,而是去控制它。(今日份触动值达标~)

goctl工具提供了一键生成api(http)项目与rpc项目的方式,只需编写资源描述文件.proto、.api,即可省去1小时手动搭建服务框架的时间~
还支持model层代码生成,构建docker镜像,编写k8s yaml文件… 就。很强大

安装goctl:

GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest

2 生成http服务与rpc服务

2.1 生成http服务

以下命令也利用goland安装一个goctl插件,全部都能交互式操作哦~

先创建一个.api模板,定义自己的服务与接口:

goctl api -o tpl/user.api

文件内容:

syntax = "v1"

info (
	title:   "My User Service"
	desc:    "My User Service"
	author:  "xxx"
	email:   "xxx@xxx.com"
	version: "1.0"
)

type GetUserRequest {
	id string
}

type GetUserResponse {
	name     string
	email    string
}

type LoginRequest {
	id       string
	password string
}

type LoginResponse {}

//@server(
//    jwt: Auth  // 开启jwt认证
//)
service user {
	@doc "根据id查询用户信息"
	@handler GetUser
	get /user/:id (GetUserRequest) returns (GetUserResponse)

	@doc "用户登录"
	@handler Login
	post /user/login (LoginRequest) returns (LoginResponse)
}

定义好.api模板后,就可以一键生成自己的http服务了:

goctl api go -api tpl/user.api -dir ./cmd/api/user -style gozero

可以看到goctl帮我们生成了完成的服务框架:

├── etc
│   └── user.yaml               #配置文件,根据服务需要修改,比如添加mysql配置、redis配置
├── internal
│   ├── config                  #对应yaml配置
│   │   └── config.go           
│   ├── handler                 #http服务的路由
│   │   ├── getuserhandler.go
│   │   ├── loginhandler.go
│   │   └── routes.go
│   ├── logic                   #业务接口逻辑,需要自己补充
│   │   ├── getuserlogic.go
│   │   └── loginlogic.go
│   ├── svc
│   │   └── servicecontext.go   #上下文
│   └── types
│       └── types.go
└── user.go                     #main入口

2.2 生成rpc服务

同样的步骤,要先创建一个.proto模板,定义好自己的服务和接口:

goctl rpc -o tpl/user.proto

.proto内容:

syntax = "proto3";

package user;
option go_package="./user";

message GetUserRequest {
  string id = 1;
}

message GetUserResponse {
  string name = 1;
  string email = 2;
}

message LoginRequest {
  string id = 1;
  string password = 2;
}

// todo: 不支持引用第三方google.protobuf.Empty
message LoginResponse {
}

service User {
  rpc GetUser(GetUserRequest) returns(GetUserResponse);
  rpc Login(LoginRequest) returns(LoginResponse);
}

一键生成rpc服务框架结构:

goctl rpc protoc tpl/user.proto --go_out=./cmd/rpc/user --go-grpc_out=./cmd/rpc/user --zrpc_out=./cmd/rpc/user

rpc生成后的目录结构:

├── etc
│   └── user.yaml               #配置文件,根据服务需要修改,比如添加mysql配置、redis配置
├── internal
│   ├── config                  #对应yaml配置
│   │   └── config.go           
│   ├── logic                   #业务逻辑,需要自己补充
│   │   ├── getuserlogic.go
│   │   └── loginlogic.go
│   ├── server                  #grpc server接口实现,直接调用了logic
│   │   └── userserver.go
│   └── svc
│       └── servicecontext.go   #上下文
├── user
│   ├── user_grpc.pb.go
│   └── user.pb.go
├── userclient
│   └── user.go
└── user.go

2.3 http与rpc的统一服务

使用上述方式可以分别生成http服务与rpc服务,那么我们如果想把http与rpc封在一个服务中,要怎么做呢? 将上述过程全部实现一遍吗?

goctl并不支持生成一个包含api和rpc服务的单一main入口的方式,但goctl提供了一种gateway支持,可以将定义好的rpc服务转换为api服务,也就是说,我们仅需定义rpc接口,然后使用gateway方式生成api.

完整流程:
(1)使用goctl生成rpc服务的代码
(2)创建配置文件 gateway.yaml,如下:

Name: hello-gateway
Host: localhost
Port: 8000 #api端口
Upstreams:
  - Grpc:
      Target: localhost:9000 #rpc端口, 与rpc中定义的一致
    Mappings:
      - Method: get
        Path: /ping
        RpcPath: hello.Hello/Ping #api接口对应的rpc接口,格式{serviceName}.{method}

(3)改造rpc服务,将入口main函数改为服务启动函数,接收调用

package hello

import (
	//...
)

func RunRpcServer(configFile string) {
	var c config.Config
	conf.MustLoad(configFile, &c)
	ctx := svc.NewServiceContext(c)

	s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
		hello.RegisterHelloServer(grpcServer, server.NewHelloServer(ctx))
		reflection.Register(grpcServer)
	})
	defer s.Stop()

	s.Start()
}

(4)编写一个新的main.go入口文件,初始化这两个服务

package main

import (
	"flag"
	"fmt"
	"github.com/zeromicro/go-zero/core/conf"
	"github.com/zeromicro/go-zero/gateway"
	"test/go-zero/cmd/rpc/hello"
	"time"
)

var (
	rpcConfigFile     = flag.String("rpc_conf", "rpc/hello/etc/config.yaml", "rpc config file")
	gatewayConfigFile = flag.String("gw_conf", "etc/gateway.yaml", "gateway config file")
)

func main() {
	flag.Parse()

	// 开启rpc
	go hello.RunRpcServer(*rpcConfigFile)
	
	time.Sleep(time.Millisecond * 100)

	// 开启api
	var c gateway.GatewayConf
	conf.MustLoad(*gatewayConfigFile, &c)
	gw := gateway.MustNewServer(c)
	defer gw.Stop()
	go gw.Start()

	fmt.Printf("Start rpc  server at %s\n", c.Upstreams[0].Grpc.Target)
	fmt.Printf("Start http server at %+v:%+v\n", c.Host, c.Port)

	select {}
}

这样就成功打造了一个同时提供api和rcp两种方式的服务。
nice~ 开始编写自己的服务吧~

3 生成model层代码

goctl支持基于ddl生成model层代码,还可以选择不带redis cache、带redis cache生成。

目前支持mysql、pg、mongo三种数据库:

Usage:
  goctl model [command]

Available Commands:
  mongo       Generate mongo model
  mysql       Generate mysql model
  pg          Generate postgresql model

3.1 生成mysql的model层代码

先创建.sql文件,定义库表结构:

CREATE TABLE `user` (
   `id` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'ID',
   `name` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名',
   `email` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '邮箱',
   `password` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密钥',
   `create_t` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
   PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';

然后就可以根据.sql一键生成model层代码:

goctl model mysql ddl -src=./tpl/user.sql  -dir=./model/sql

可以看到生成了model层结构为:

model/sql/
├── usermodel_gen.go    #封装的db的连接操作、CRUD操作
├── usermodel.go        #model层入口
└── vars.go

若要开启带缓存模式,添加-cache参数即可:

goctl model mysql ddl -src=./tpl/user.sql -dir=./model/sql -cache

那么生成的model层入口中,是增加了cache.CacheConf这个redis cache配置参数的:

func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UserModel

可以利用这个做一些db与cache的组合操作。

3.2 生成pg的model层代码

除了上述方式根据ddl生成model层代码,还可以基于datasource生成,比如根据pg url生成:

goctl model pg datasource --url="postgres://user:123@localhost:5432/testDB?sslmode=disable" --table="*"

还没试过

3.3 生成mongo的model层代码

这个就不需要编写模板文件了,直接命令生成mongo的model层代码:

goctl model mongo --type User --dir ./model/mongo --cache

生成的结构:

model/mongo/
├── error.go
├── usermodelgen.go     #db操作,CRUD
├── usermodel.go        #model层入口
└── usertypes.go        #字段定义

mongo爱好者狂喜==



  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值