首页 > 其他分享 >golang微服务之go-zero零基础实战

golang微服务之go-zero零基础实战

时间:2024-05-22 15:53:46浏览次数:29  
标签:string err rpc golang zero api user go

golang微服务之go-zero零基础实战

1. 环境准备

  1. mysql
    提供rpc服务接口后端交互存储
  2. etcd
    提供rpc服务注册与发现

2. 文件结构

image

rpc服务接口:
1. 用户登录
2. 用户创建
3. 查询用户信息

api服务接口:
1. 用户登录
2. 用户创建
3. 查询用户信息

3. 搭建步骤

1. 搭建rpc服务

  1. 创建rpc目录
  2. 在rpc目录下创建proto文件,user.proto
syntax = "proto3";

package user;

option go_package="./user";

message UserInfoRequest{
    uint32 id = 1;
}

message UserInfoResponse{
    uint32 id = 1;
    string username = 2;
    bool gender = 3;
}

message UserCreateRequest{
    string username = 1;
    string password = 2;
    bool gender = 3;
}

message UserCreateResponse{
    uint32 id = 1;
    string err = 2;
}

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

message UserLoginResponse{
    bool success = 1;
    uint32 id = 2;
}

service user{
    rpc UserInfo(UserInfoRequest)returns(UserInfoResponse);
    rpc UserCreate(UserCreateRequest)returns(UserCreateResponse);
    rpc UserLogin(UserLoginRequest)returns(UserLoginResponse);
}

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

此处,rpc定义 用户登录、用户创建、获取用户信息 ,三个接口以及请求和响应结构体
使用goctl生成代码
goctl rpc protoc user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=.

  1. 修改rpc/etc/user.yaml,配置etcd服务器地址、key、mysql连接地址
Name: user.rpc
ListenOn: 0.0.0.0:8080
Etcd:
  Hosts:
  - 10.100.11.111:2379
  Key: user.rpc
  
Mysql:
  DataSource: root:123456@tcp(10.100.11.111:3306)/db3?parseTime=true
  1. 修改rpc/internal/config/config.go,添加mysql配置项解析
type Config struct {
	zrpc.RpcServerConf
	Mysql struct{
		DataSource string
	}
}
  1. 修改rpc/internal/svc/servicecontext.go,为svc添加DB服务依赖
type ServiceContext struct {
	Config config.Config
	DB  *gorm.DB
}

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

init_gorm:

func InitGorm(MysqlDataSource string) *gorm.DB{
	db, err := gorm.Open(mysql.Open(MysqlDataSource), &gorm.Config{})
	if err != nil {
		panic("connect fail")
	}else{
		fmt.Println("connect success")
	}
	db.AutoMigrate(&models.UserModel{})
	return db
}
  1. 创建用户model,供数据库使用,修改rpc/models/user_model.go
type UserModel struct{
	gorm.Model
	Username string `gorm:"size:32" json:"user"`
	Password string `gorm:"size:64" json:"password"`
	Gender bool `gorm:"size:64" json:"gender"`
}
  1. 编写logic,用户登录、创建、获取信息的逻辑部分,数据库交互
    用户登录logic:
	var userInfo models.UserModel
	err := l.svcCtx.DB.Where("username = ? and password = ?", in.Username, in.Password).First(&userInfo).Error
	if err != nil {
		return &user.UserLoginResponse{
			Success: false,
		}, err
	}
	return &user.UserLoginResponse{
		Success: true,
		Id: uint32(userInfo.ID),
	}, nil

添加用户logic:

	var model models.UserModel
	pd = new(user.UserCreateResponse)
	err = l.svcCtx.DB.Take(&model, "username = ?", in.Username).Error
	if err == nil {
		pd.Err = "user exist"
		return
	}
	model = models.UserModel{
		Username: in.Username,
		Password: in.Password,
		Gender:   in.Gender,
	}
	err = l.svcCtx.DB.Create(&model).Error
	if err != nil {
		logx.Error(err)
		pd.Err = err.Error()
		err = nil
		return
	}
	fmt.Println(model.ID)
	pd.Id = uint32(model.ID)
	return &user.UserCreateResponse{}, nil

查询用户logic

	var userInfo models.UserModel
	err := l.svcCtx.DB.Take(&userInfo, in.Id).Error
	if err != nil {
		return nil, errors.New("user not exist")
	}
	return &user.UserInfoResponse{
		Id:       uint32(userInfo.ID),
		Username: userInfo.Username,
		Gender: userInfo.Gender,
	}, nil

至此,rpc服务三个接口编写完成,可通过apifox调用rpc接口验证

2. api服务搭建

  1. 新建api目录、
  2. 新建user.api,api文件,编辑三个接口的定义、请求及响应结构体
type UserCreateRequest {
	Username string `json:"username"`
	Password string `json:"password"`
	Gender   bool   `json:"gender"`
}

type UserInfoRequest {
	Id uint `path:"id"`
}

type UserInfoResponse {
	Id       uint   `json:"id"`
	Username string `json:"username"`
	Gender   bool   `json:"gender"`
}

@server (
	prefix: /api/users
	jwt:    Auth
)
service users {
	@handler userCreate
	post / (UserCreateRequest) returns (string)

	@handler userInfo
	get /info/:id (UserInfoRequest) returns (UserInfoResponse)
}

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

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

// goctl api go -api user.api -dir .

  1. 生成api服务文件
    goctl api go -api user.api -dir .

  2. 修改api/etc/users.yaml,配置jwt auth及rpc服务地址、key相关配置

Name: users
Host: 0.0.0.0
Port: 8888
Auth:
  AccessSecret: a123456aaa
  AccessExpire: 86400
UserRpc:
  Etcd:
    Hosts:
    - 10.100.13.120:2379
    Key: user.rpc
  1. 修改api/internal/config/config.yaml,添加userRpc及jwtAuth相关配置解析
type Config struct {
	rest.RestConf
	UserRpc zrpc.RpcClientConf
	Auth struct{
		AccessSecret string
		AccessExpire int64
	}
}
  1. 修改api/internal/svc/servicecontext.go,为svc添加rpc服务依赖
type ServiceContext struct {
	Config config.Config
	UserRpc userclient.User
	
}

func NewServiceContext(c config.Config) *ServiceContext {
	return &ServiceContext{
		Config: c,
		UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
	}
}
  1. 编写logic,调用rpc服务接口
    用户登录:
	res, err := l.svcCtx.UserRpc.UserLogin(l.ctx, &userclient.UserLoginRequest{
		Username: req.Username,
		Password: req.Password,
	})
	if err != nil {
		return "", errors.New("login fail")
	}
	token, err := jwts.GenToken(&jwts.JwtPayLoad{
		UserID:   uint(res.Id),
		Username: req.Username,
		Role: 1,
	}, l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire)
	if err != nil {
		return "", errors.New("login fail")
	}
	return token, nil

创建用户:

	response, err := l.svcCtx.UserRpc.UserCreate(l.ctx, &user.UserCreateRequest{
		Username: req.Username,
		Password: req.Password,
	})
	if err != nil {
		return "", err
	}
	if response.Err!= ""{
		return "", errors.New(response.Err)
	}
	return

查询用户:

	response, err := l.svcCtx.UserRpc.UserInfo(l.ctx, &user.UserInfoRequest{
		Id: uint32(req.Id),
	})
	if err != nil {
		return nil, err
	}
	return &types.UserInfoResponse{
		Id: uint(response.Id),
		Username: response.Username,
		Gender: response.Gender,
	}, nil

至此,api服务接口搭建完成

4. 启动服务

rpc:
go run user.go

api:
go run users.go

标签:string,err,rpc,golang,zero,api,user,go
From: https://www.cnblogs.com/brandonv/p/18206429

相关文章

  • Golang初学:vs code, launch.json, Run
    goversiongo1.22.1windows/amd64Windows11+amd64x86_64x86_64GNU/Linuxvscode1.89.1--- 序章在vscode开发go程序,之前总是在终端(terminal)输入命令(gorun.)来执行。不过,这不是最高效的方式。通过添加并配置launch.json可以更方便地程序仅运行(Ctrl+F5......
  • (转)Go 每日一库之 cast
    原文:https://juejin.cn/post/6844904056750620679简介今天我们再来介绍spf13大神的另一个库cast。cast是一个小巧、实用的类型转换库,用于将一个类型转为另一个类型。最初开发cast是用在hugo中的。快速使用先安装: 复制代码$gogetgithub.com/spf13/cast后使用......
  • go minio 设置访问权限
    bucket权限桶默认可以有三种AccessPolicy策略:public、custom、private。public:不经过任何认证可以直接访问资源custom:自定义策略AccessRuleprivate:未经授权不能进行任何操作,所有AccessRules失效策略为custom{"Version":"2012-10-17","Statement":[......
  • go多版本切换
    VSCode中如何快速切换golang版本而无影响?如何安装多版本参考链接:https://go.dev/doc/manage-install当已安装某个版本后,执行如下命令goinstallgolang.org/dl/[email protected]执行第一行命令后,会在GOPATH中新增go1.19.7。执行第二行命令后,会在sdk目......
  • golang 类型断言和 var _ T = expression 写法
     类型断言(TypeAssertion)在Go语言中用于检查一个接口值的具体类型,并从中获取该类型的值。它允许你声明并访问接口变量内部存储的非接口类型的值。有两种主要的类型断言形式:value,ok:=i.(T):这种形式会检查接口i是否持有类型T的值。如果成功,value将是T类型的值,ok......
  • golang select 和外层的 for 搭配
     select语句通常与for循环搭配使用,但并不是必须的。在某些情况下,select可能会直接放在一个独立的goroutine中,没有外层的for循环。这通常发生在你知道只会有一次或有限次操作的情况下。例如,你可能有一个简单的goroutine,它等待一个特定的channel信号,然后执行一次操作:package......
  • 【DRF_02】基于Django CBV实现
    路由系统fromdjango.urlsimportpathfromapp01.viewsimportcbv_demourlpatterns=[#path('admin/',admin.site.urls),path('cbv/demo/',cbv_demo.StudentsView.as_view()),]CBV视图fromdjango.viewsimportViewfromdjango.sh......
  • git:Unable to negotiate问题解决
    场景说明:安装了Gitblit(自架的代码仓库服务)发现部分电脑无法推代码,报错误如下:Unabletonegotiatewith****port22:nomatchinghostkeytypefound.Theiroffer:ssh-rsa并排队了账户权限问题。解决方案:1.打开问题电脑的系统盘的当前登陆用户文件夹('C:\Users\你当前的......
  • Google I/O 2024 All In One
    GoogleI/O2024AllInOnehttps://io.google/2024https://io.google/2024/intl/zh/demoshttps://io.google/2024/explore/intl/zh/?q=webcookieshttps://io.google/2024/explore/2f6e1e21-3e91-407e-93fc-364c4500cd23/intl/zh/(......
  • 【go】【gorm】
    @目录写在前面题目解题难度参考资料基础/标准库/第三方库golang导航编程规范算法|面试项目写在前面相关博文个人博客首页免责声明:仅供学习交流使用!开源框架可能存在的风险和相关后果将完全由用户自行承担,本人不承担任何法律责任。题目解题难度更详细的GORM速查表......