go-zero 的使用

目录

1. 生成 user api 服务

2. 生成 user rpc 服务

3. 生成 user model 模型

4. 编写 user rpc 服务

1 修改配置文件 user.yaml

2 添加 user model 依赖

3 添加用户登录逻辑 Login

5. 编写 user api 服务

1 修改配置文件user.yaml

2 添加 user rpc 依赖

3 添加用户登录逻辑 Login

6. 启动服务

启动rpc服务

启动api服务

登录成功,查看缓存 


本文章讲解使用go-zero生成一个微服务的过程。其中的一些命令或者名不太熟悉的话,可以参考go-zero官网。

项目名字叫zero。创建zero目录,并在该目录下创建user目录。

1. 生成 user api 服务

在user目录下添加api目录,在api目录添加如下的api文件。 

syntax = "v1"type LoginReq {Mobile string `json:"mobile"`Password string `json:"password"`
}type LoginResponse {UserId int64 `"json:"userId"`Token string `json:"token"`
}@server (prefix: v1
)
service user {@handler loginpost /user/login (LoginReq) returns (LoginResponse)
}

 在user/api下执行

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

执行生成后,api目录结构体如下

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

2. 生成 user rpc 服务

在user目录下创建rpc目录。在rpc目录下添加如下的proto文件。

syntax="proto3";package user;option go_package="./user";//用户登录
message LoginRequest{string mobile=1;string Password=2;
}message LoginResponse{int64 Id=1;
}service User{rpc Login(LoginRequest)returns(LoginResponse);
}

在user/rpc下执行

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

 执行生成后,rpc目录结构如下

.
├── etc
│   └── user.yaml
├── internal
│   ├── code
│   │   └── code.go
│   ├── config
│   │   └── config.go
│   ├── db
│   │   └── mysql.go
│   ├── logic
│   │   └── loginlogic.go
│   ├── server
│   │   └── userserver.go
│   └── svc
│       └── servicecontext.go
├── user
│   ├── user_grpc.pb.go
│   └── user.pb.go
├── userclient
│   └── user.go
├── user.go
└── user.proto

3. 生成 user model 模型

在user目录添加model目录,在model中添加如下的user.sql文件。

CREATE TABLE `user` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`name` varchar(255)  NOT NULL DEFAULT '' COMMENT '用户姓名',`mobile` varchar(255)  NOT NULL DEFAULT '' COMMENT '用户电话',`password` varchar(255)  NOT NULL DEFAULT '' COMMENT '用户密码',`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`),KEY  `password` (`password`) ,UNIQUE KEY `idx_mobile_unique` (`mobile`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;

在model目录中执行

goctl model mysql ddl --src user.sql --dir . -c

-c表示使用缓存。 

 执行生成后,model目录结构体如下

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

在usermodel_gen.go文件中,生成了一些基础的查询语句。 

  • 注意到user表中有3个key。主键和唯一键是可以确定一行数据的,而KEY  `password`是普通的键,所以生成了通过id,通过mobile查找数据的语句。没有生成通过password查找的语句。
  • 而且要注意到,这里是使用了缓存了,一般是使用redis。
//usermodel_gen.go
var (..................cacheUserIdPrefix     = "cache:user:id:"cacheUserMobilePrefix = "cache:user:mobile:"
)type (userModel interface {Insert(ctx context.Context, data *User) (sql.Result, error)FindOne(ctx context.Context, id uint64) (*User, error)FindOneByMobile(ctx context.Context, mobile string) (*User, error)Update(ctx context.Context, data *User) errorDelete(ctx context.Context, id uint64) error}defaultUserModel struct {sqlc.CachedConntable string}User struct {Id         uint64    `db:"id"`Name       string    `db:"name"`     // 用户姓名Mobile     string    `db:"mobile"`   // 用户电话Password   string    `db:"password"` // 用户密码CreateTime time.Time `db:"create_time"`UpdateTime time.Time `db:"update_time"`}
)

4. 编写 user rpc 服务

1 修改配置文件 user.yaml

  • 因为需要使用数据库MySql,所以我们需要配置数据库的参数,所以需要在user.yaml中填写数据库相关的参数
  • 而因为rpc是需要用到Etcd(用于服务注册发现等),所以还需要添加Etcd的配置
  • 在model中是使用了缓存的,所以也需要添加缓存的配置
Name: user.rpc
ListenOn: 0.0.0.0:8080#Etcd部分和Mysql部分是新添加的
Etcd:Hosts:- 127.0.0.1:2379Key: user.rpcMysql:datasource: "root:wook1847@tcp(127.0.0.1:3306)/zero?charset=utf8mb4&parseTime=True&loc=Local"
CacheRedis:
- Host: 127.0.0.1:5678Type: nodePass: 123456

2 添加 user model 依赖

  • 添加 Mysql 服务配置的实例化

在生成的config目录中有config.go文件,该文件中是用于解析配置文件的结构体。而这里我们添加了MySql配置,所以需要添加相关结构体来进行解析。而rest.RestConf中就带有etcd的(看源码),所以不用写etcd的。

type Config struct {zrpc.RpcServerConfMysqlConfig Mysql `json:"mysql"`    //添加mysql的配置CacheRedis  cache.CacheConf
}type Mysql struct {Datasource    string
}
  • 注册服务上下文 user model 的依赖

在生成是svc目录中的 servicecontext.go文件,后续我们就是使用该文件中的ServiceContext。而要想可以使用mysql,那就需要在其添加该依赖。

package svcimport ("mall/user/model""mall/user/rpc/internal/config""github.com/zeromicro/go-zero/core/stores/sqlx"
)type ServiceContext struct {Config    config.ConfigUserModel model.UserModel    //添加数据库的依赖
}func NewServiceContext(c config.Config) *ServiceContext {conn := sqlx.NewMysql(c.MysqlConfig.Datasource)return &ServiceContext{Config:    c,UserModel: model.NewUserModel(conn, c.CacheRedis),}
}

3 添加用户登录逻辑 Login

接着看生成的logic目录中的loginlogic.go文件。这里就是我们要写的业务逻辑地方。logic目录中的文件是我们主要写代码的地方。在Login方法中添加业务逻辑。

type LoginLogic struct {ctx    context.ContextsvcCtx *svc.ServiceContextlogx.Logger
}func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {return &LoginLogic{ctx:    ctx,svcCtx: svcCtx,Logger: logx.WithContext(ctx),}
}func (l *LoginLogic) Login(in *user.LoginRequest) (*user.LoginResponse, error) {// todo: add your logic here and delete this lineres, err := l.svcCtx.UserModel.FindOneByMobile(l.ctx, in.Mobile)if err != nil {if err == model.ErrNotFound {return &user.LoginResponse{}, nil}return nil, err}if res.Password!=in.Password{return nil,fmt.Errorf("password id wrong")}return &user.LoginResponse{Id: int64(res.Id)}, nil
}

5. 编写 user api 服务

其过程和编写user rpc服务是类似的。

1 修改配置文件user.yaml

因为我们在api中需要使用rpc,所以我们就需要用到etcd,所以就需要etcd的配置。

Name: user
Host: 0.0.0.0
Port: 8888#添加user rpc的etcd配置
UserRpc:Etcd:Hosts:- 127.0.0.1:2379Key: user.rpc#要是还需要其他服务的rpc,那就需要添加的
# PayRpc:
#   Etcd:
#     Hosts:
#     - 127.0.0.1:2379
#     Key: pay.rpc

2 添加 user rpc 依赖

  • 添加 user rpc 服务配置的实例化

在user.yaml中添加了user rpc的etcd配置后,那就需要再config.go文件中添加对应的结构体来解析配置。

而前面不是说了,etcd的结构体是rest.RestConf就带有的,不用填写了吗?

这不是这个意思的。这个是对应user rpc的etcd配置的。要是在api中还需要用其他服务,比如支付服务,而支付服务又是一个微服务,那就又要添加pay rpc的etcd配置的。

type Config struct {rest.RestConfUserRpc zrpc.RpcClientConf// PayRpc zrpc.RpcClientConf	要是需要该服务的话,就需要添加
}
  • 添加 user rpc 服务配置的实例化
type ServiceContext struct {Config config.ConfigUserRpc userclient.User    //添加user rpc使用
}func NewServiceContext(c config.Config) *ServiceContext {return &ServiceContext{Config:  c,UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),}
}

3 添加用户登录逻辑 Login

在生成的logic目录中的loginlogic.文件。这里就是我们要写的业务逻辑。

type LoginLogic struct {logx.Loggerctx    context.ContextsvcCtx *svc.ServiceContext
}func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {return &LoginLogic{Logger: logx.WithContext(ctx),ctx:    ctx,svcCtx: svcCtx,}
}//在该方法中添加我们的业务逻辑
func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.LoginResponse, err error) {// todo: add your logic here and delete this lineres, err := l.svcCtx.UserRpc.Login(l.ctx, &userclient.LoginRequest{Mobile:   req.Mobile,Password: req.Password,})if err != nil {return nil, err}if res != nil && res.Id == 0 {return nil, fmt.Errorf("has not this user")}//成功后,生成tokentoken := "1234534345"return &types.LoginResponse{UserId: res.Id, Token: token}, nil
}

6. 启动服务

因为api服务是依赖rpc服务,所以先启动rpc服务,再启动api服务。

启动rpc服务

在user/api中执行

go run user.go

启动api服务

在user/rpc中执行

go run user.go

登录成功,查看缓存 

登录成功后,Redis中会缓存该用户的数据。因为生成model时候,是使用了缓存的。还记得在model环节生成的usermodel_gen.go文件。这两个就是key,拼接上对应的id或者mobile即可。

//usermodel_gen.go
var (..................cacheUserIdPrefix     = "cache:user:id:"cacheUserMobilePrefix = "cache:user:mobile:"
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/58749.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基金委:目前资助率过低,危害大,应提升至30~35%,增大青年、面上项目经费

国家基金委 近日,国家基金委发表题为《近十年 NSF资助率和资助强度上升 对我国科学基金资助工作的启示》文章,文章基于近十年 NSF总体资助变化,提出对我国科学基金资助工作启示,阐述了国家自然基金项目资助率下降情况、危害,并提…

NPM 包开发与优化全面指南

前言 Hey, 我是 Immerse系列文章首发于【Immerse】,更多内容请关注该网站转载说明:转载请注明原文出处及版权声明! 1. 理解 NPM 包的结构 1.1 package.json 文件:包的核心 package.json文件是 NPM 包的中央配置,定…

学Linux的第六天

目录 账户和组管理 工作组管理 创建工作组groupadd 修改工作组groupmod 添加/删除组成员gpasswd 删除工作组groupdel 查看用户登录系统的情况 users查看当前登录系统的用户 last命令 lastlog命令 w命令 显示登录到系统的用户信息 who命令 Linux文件系统权限 文件…

来康生命科技有限公司心率监测解决方案在健身房与康养机构的应用探索

引言 随着科技的日新月异,智能健康服务正逐步成为现代健康管理不可或缺的一环。来康生命科技有限公司,凭借其在智能物联集成交互领域的自主创新能力,推出了一款集蓝牙物联网、蓝牙手环、数据云与管理终端于一体的心率监测解决方案。此方案专…

在 .NET 8 Web API 中实现 Entity Framework 的 Code First 方法

本次介绍分为3篇文章: 1:.Net 8 Web API CRUD 操作.Net 8 Web API CRUD 操作-CSDN博客 2:在 .Net 8 API 中实现 Entity Framework 的 Code First 方法https://blog.csdn.net/hefeng_aspnet/article/details/143229912 3:.NET …

C++类和对象上

1. 类的定义 1.1 类定义格式 • class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后⾯分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的⽅法或者成员函数。…

NineData云原生智能数据管理平台新功能发布|2024年10月版

10 月发布内容 本月发布 7 项更新,其中重点发布 2 项、功能优化 3 项、性能优化 1 项、其他发布 1 项。 重点发布​ 数据库 Devops - 数据生成​ NineData 支持在数据库中自动生成符合特定业务场景的随机数据,用于模拟实际生产环境中的数据情况&…

BGP路径属性与路由反射器

前言 IBGP水平分割规则用于防止AS内部产生环路,在很大程度上杜绝了IBGP路由产生环路的可能性,但是同时也带来了新的问题:BGP路由在AS内部只能传递一跳,如果建立IBGP对等体全互联模型又会加重设备的负担。 BGP 路径属性 AS_Path …

医学和生信web APP 平台- Appmatrix

医学(和生信)web APP 平台- Appmatrix 最近使用shinyproxy将平时所构建的shiny和streamlit医学类应用汇集在一起,实现一站式访问,另外,使用了自己电脑内网穿透,一定程度上缓解了数据分析类APP消耗计算资源…

Rust 力扣 - 1456. 定长子串中元音的最大数目

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们遍历长度为k的窗口,我们只需要记录窗口内的元音字母数量即可,遍历过程中刷新最大数目 题解代码 impl Solution {pub fn max_vowels(s: String, k: i32) -> i32 {let s s.as_byt…

Centos系统新增网卡后获取不到网卡的IP地址解决方法

一、问题描述 当我们给Centos系统添加了新的网卡后,使用查看IP地址命令【ip addr】时,发现新网卡没有获取到对应的IP地址信息,如下图所示: 二、解决方法 有两种解决方法:一种是自动获取IP地址;另外一种是手动配置IP地址; 2.1、自动获取IP地址 #自动获取网卡的IP地址命…

跨境卖家必备!好用的独立站建站工具推荐 !

对于跨境卖家来说,拥有一个独立站是拓展海外市场、提升品牌影响力的重要途径。而选择一款好用的独立站建站工具,则是成功搭建独立站的关键。 一、为什么跨境卖家需要独立站? 在跨境电商领域,独立站具有诸多优势。首先&#xff0c…

Windows Qt 6安装Oracle QOCI SQL Driver插件

本文参考 QOCI for the Oracle Call Interface (OCI)。 Windows 打开 Qt 6.8.0 (MSVC 2022 64-bit)。 Setting up environment for Qt usage… Remember to call vcvarsall.bat to complete environment setup! 执行 "D:\Program Files\Microsoft Visual Studio\2022\E…

书生实战营第四期-第二关python

一、任务1:完成Leetcode 383 1.代码 class Solution:def canConstruct(self,ransomNote: str, magazine: str) -> bool: # 创建一个字典来存储 magazine 中每个字符的出现次数 char_count {} # 遍历 magazine,统计每个字符的出现次数 for char…

计算机考研,选择西安交通大学还是哈工大?

C哥专业提供——计软考研院校选择分析专业课备考指南规划 经过全面分析,2025年考研西安交通大学和哈尔滨工业大学计算机专业的报考难度对比如下: 西安交通大学计算机专业 > 哈尔滨工业大学计算机专业 对于想要报考985高校计算机专业但核心目标是优…

CentOS系统查看CPU、内存、操作系统等信息

Linux系统提供了一系列命令可以用来查看系统硬件信息,如CPU的物理个数、核数、逻辑CPU数量、内存信息和操作系统版本。 查看物理CPU、核数和逻辑CPU 在多核、多线程的系统中,了解物理CPU个数、每个物理CPU的核数和逻辑CPU个数至关重要。超线程技术进一步…

项目升级到.Net8.0 Autofac引发诡异的问题

前两天把项目升级到.Net8.0了,把.Net框架升级了,其他一些第三方库升级了一部分,升级完以后项目跑不起来了,报如下错误: An unhandled exception occurred while processing the request. DependencyResolutionExcepti…

十八、【智能体】数据库:未来科技的大脑

在上一篇中我们讲到了 **变量 ** , 变量 的作用是保存用户个人信息,让 Bot记住用户的特征,使回复更加个性化。 上一篇内容为:https://blog.csdn.net/qq_40585384/article/details/143272599 但变量有一个缺点——存储的信息太单…

web文件包含include

php伪协议 在 PHP 中,伪协议(Pseudo Protocols) 也被称为 流包装器,这些伪协议以 php:// 开头,后面跟着一些参数,用于指定 要执行的操作 或 需要访问的资源。 伪协议表明这些协议并不是一个 真实的外部协议…

Diving into the STM32 HAL-----USART

如今,电子行业有许多串行通信协议和硬件接口可用。其中之一是通用同步/异步接收器/发射器接口,也简称为 USART。几乎每个微控制器都至少提供一个 UART 外设。几乎所有的 STM32 MCU 都提供至少两个 UART/USART 接口,但根据 MCU 封装支持的 I/O…