Golang 微服务框架go-zero

api文档 swagger

  1. 安装swagger
    go install github.com/zeromicro/goctl-swagger@latest
  2. 执行生成user.json文件
    goctl api plugin -plugin goctl-swagger="swagger -filename user.json -host 127.0.0.1:8080" -api user.api -dir ./doc
    其中user.api中的文件见上一篇blog
    这里就是把user.json 放到当前目录下的doc文件夹中,注意这里的-host 就是swagger请求的路径
    3.启动docker
    docker run --rm -p 8087:8080 -e SWAGGER_JSON=/foo/user.json -v $PWD:/foo swaggerapi/swagger-ui
    启动之后在浏览器访问
    127.0.0.1:8083 就能看到swagger界面

在这里面接口/api/users/info请求的地址 就是上面host的地址

go-zero 使用mysql

  • 创建一个表
    model/user.sql

    CREATE TABLE `user` (
                        `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
                        `username` varchar(36) DEFAULT NULL,
                        `password` varchar(64) DEFAULT NULL,
                        PRIMARY KEY (`id`),
                        KEY `user_index` (`username`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  • 生成model
    goctl model mysql ddl --src user.sql --dir .
    结果如下

    ├── user.sql
    ├── usermodel.go
    ├── usermodel_gen.go
    └── vars.go

  • api文件

type LoginRequest {
    Username string `json:"username"`
    Password string `json:"password"`
}

@server (
    prefix: /api/users
)
service users {
    @handler login
    post /login returns (string)
}

执行goctl api go -api user.api -dir . 后结果如下

├── etc
│   └── users.yaml
├── internal
│   ├── config
│   │   └── config.go
│   ├── handler
│   │   ├── loginhandler.go
│   │   └── routes.go
│   ├── logic
│   │   └── loginlogic.go
│   ├── svc
│   │   └── servicecontext.go
│   └── types
│   └── types.go
├── user.api
└── users.go

  • 配置
    1 在etc/user.yaml 里增加 mysql的配置
    Mysql:
    DataSource: root:root@tcp(127.0.0.1:3306)/zero_db?charset=utf8mb4&parseTime=True&loc=Local
    2 在internal/config/config.go 中

    type Config struct {
        rest.RestConf
        //增加以下内容
        Mysql struct {
            DataSource string
        }
    }

    3 在internal/svc/servicecontext.go中

type ServiceContext struct {
    Config    config.Config
    UserModel model.UserModel
    Mysql     struct {
        DataSource string
    }
}

func NewServiceContext(c config.Config) *ServiceContext {
    mysqlConn := sqlx.NewMysql(c.Mysql.DataSource)
    return &ServiceContext{
        Config:    c,
        UserModel: model.NewUserModel(mysqlConn),
    }
}

就可以使用

type (
    userModel interface {
        Insert(ctx context.Context, data *User) (sql.Result, error)
        FindOne(ctx context.Context, id int64) (*User, error)
        FindOneByUserName(ctx context.Context, username string) (*User, error)
        Update(ctx context.Context, data *User) error
        Delete(ctx context.Context, id int64) error
    }

定义的方法了

例如在loginlogic中

func (l *LoginLogic) Login() (user *model.User, err error) {
    id := int64(1)
    res, err := l.svcCtx.UserModel.FindOne(l.ctx, id)
    if err != nil {
        return res, err
    }
    fmt.Println(res)
    return res, nil
}

go-zero 使用gorm

1 安装gorm
go get -u gorm.io/gorm
go get gorm.io/driver/mysql

2 配置yaml文件
Mysql:
DataSource: root:root@tcp(127.0.0.1:3306)/zero_db?charset=utf8mb4&parseTime=True&loc=Local

3 在servicecontext.go中 调整代码如下

type ServiceContext struct {
    Config config.Config
    //增加DB字段
    DB     *gorm.DB
}

func NewServiceContext(c config.Config) *ServiceContext {
    mysqlDb := InitGorm(c.Mysql.DataSource)
    return &ServiceContext{
        Config: c,
        DB:     mysqlDb,
    }
}

func InitGorm(MysqlDataSource string) *gorm.DB {
    db, err := gorm.Open(mysql.Open(MysqlDataSource), &gorm.Config{})
    if err != nil {
        panic("连接mysql数据库失败, error=" + err.Error())
    } else {
        fmt.Println("连接mysql数据库成功")
    }
    return db
}

4 在loginlogic中可以使用了

func (l *LoginLogic) Login(req *types.Request) (resp *sql.NullString, err error) {

    var user model.User
    //gorm语法
    err = l.svcCtx.DB.Take(&user, "username = ?", req.Name).Error

    if err != nil {
        return nil, err
    }

    return &user.Username, nil
}

RPC服务分组

就是把多个服务的代码分开不同的文件夹来存放

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

message UserInfoRequest{
  uint32  user_id = 1;//序列号的位置
}

message UserInfoResponse{
  uint32  user_id = 1;
  string username = 2;
}

message UserCreateRequest{
  string username = 1;
  string password = 2;
}

message UserCreateResponse{
  string err = 1;
}

service UserInfo{
  rpc UserInfo(UserInfoRequest) returns (UserInfoResponse);

}

service UserCreate{
  rpc UserCreate(UserCreateRequest) returns (UserCreateResponse);
}

执行命令:
goctl rpc protoc user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=. --style goZero -m

这里是执行rpc的文件,输出文件夹为types, rpc的生成的文件为当前目录
--style 是文件夹命名风格,goZero 代表小驼峰样式。
-m 代表多个服务

生成的文件夹目录

.
├── client
│   ├── usercreate
│   │   └── userCreate.go
│   └── userinfo
│       └── userInfo.go
├── etc
│   └── user.yaml
├── internal
│   ├── config
│   │   └── config.go
│   ├── logic
│   │   ├── usercreate
│   │   │   └── userCreateLogic.go
│   │   └── userinfo
│   │       └── userInfoLogic.go
│   ├── server
│   │   ├── usercreate
│   │   │   └── userCreateServer.go
│   │   └── userinfo
│   │       └── userInfoServer.go
│   └── svc
│       └── serviceContext.go
├── types
│   └── user
│       ├── user.pb.go
│       └── user_grpc.pb.go
├── user.go
└── user.proto

可以看到userCreate 和userInfo 分成两个文件夹

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注