从零开始实现基于go-zero框架的微服务电商项目(二)——User服务的基础搭建

从零开始实现基于go-zero框架的微服务电商项目(二)——User服务的基础搭建

项目地址liuxianloveqiqi/XianShop: 使用go-zero搭建的电商项目 (github.com)

API

首先在api包下新建user.api文件,我们需要四个接口:

  1. 根据手机号发送验证码
  2. 根据手机号和验证码进行注册/登陆,成功后返回token
  3. 根据手机号/邮箱,密码进行登陆
  4. 查询用户信息

编写user.api文件;

syntax = "v1"  // 版本号

// 接口信息
info(
	title: "XianShip/user.api"
	author: "liuxian"
	version: "1.0.0"
)
type (
	// 手机号注册/登陆
	RegisterReq {
		UserPhone string `json:"userPhone"`
		VeCode    string `json:"veCode"`
	}
	RegisterByPhoneRep {
		UserPhone string `json:"userPhone"`
	}
	LoginReq {
		PhoneOrEmail string `json:"phoneOrEmail"` // 手机号或者邮箱
		PassWord     string `json:"PassWord"`     // 用户密码,MD5加密
	}

	userInfoReq {
		UserId int64 `json:"userId"` // 用户id
	}

	UserInfoResply {
		Code    int64         `json:"Code"`
		Message string        `json:"Message"`
		Data    *UserInfoItem `json:"Data"`
	}
	RegisterByPhoneResply {
		Code    int64  `json:"Code"`
		Message string `json:"Message"`
		VeCode  string `json:"veCode"`
	}
	UserInfoItem {
		UserID    int64  `json:"userId"`    // 用户id
		UserNick  string `json:"UserNick"`  // 用户昵称
		UserFace  string `json:"UserFace"`  // 用户头像地址
		UserSex   int64  `json:"UserSex"`   // 用户性别:0男,1女,2保密
		UserEmail string `json:"UserEmail"` // 用户邮箱
		UserPhone string `json:"UserPhone"` // 用户手机号
	}
	CommonResply {
		Code    int64  `json:"Code"`
		Message string `json:"Message"`
		Data    string `json:"Data"`
	}
	TokenResply {
		Code         int64  `json:"Code"`
		Message      string `json:"Message"`
		AccessToken  string `json:"accessToken"`
		RefreshToken string `json:"refreshToken"`
	}
)

@server(
	prefix: account
)

service user-api {
	@doc(
		summary: "发验证码"
	)
	@handler Sendcode
	post /sendcode (RegisterByPhoneRep) returns (RegisterByPhoneResply)
	@doc(
		summary: "用户验证码形式注册/登陆"
	)
	@handler Register
	post /register (RegisterReq) returns (TokenResply)
	@doc(
		summary: "用户密码形式登录"
	)
	@handler Login
	post /login (LoginReq) returns (TokenResply)
}

@server(
	middleware: JWT // 路由中间件声明
)

service user-api {
	@doc(
		summary: "用户信息"
	)
	@handler userInfo
	post /userinfo (userInfoReq) returns (UserInfoResply)
}

cd到 user/api文件下:输入$ goctl api go -api user.api -dir .

再修改etc下的user-api.yaml文件:

# user 模块配置
Name: user-api
Host: 0.0.0.0
Port: 4000
# mysql配置
Mysql:
  DataSource: root:root@(127.0.0.1:3306)/xian-shop?charset=utf8mb4&parseTime=True&loc=Asia%2FShanghai
# redis 配置
CacheRedis:
  - Host: 127.0.0.1:6379
    Pass:
    Type: node
Rpc:
  Etcd:
    Hosts:
      - 127.0.0.1:2379
    Key: user.rpc

修改config.go文件:

package config

import (
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/rest"
	"github.com/zeromicro/go-zero/zrpc"
)

type Config struct {
	rest.RestConf
	Mysql struct {
		DataSource string
	}
	CacheRedis cache.CacheConf
	Rpc        zrpc.RpcClientConf
}

config.go文件里面的东西在logic层进行业务处理的时候都可以调用,这里我们就把mysql,redis写进去

修改svc文件夹下的servicecontext.go

package svc

import (
	"XianShop/service/common"
	"XianShop/service/user/api/internal/config"
	"XianShop/service/user/model"
	"XianShop/service/user/rpc/userclient"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"github.com/zeromicro/go-zero/zrpc"
	"gorm.io/gorm"
)

type ServiceContext struct {
	Config    config.Config
	DbEngine  *gorm.DB
	UserModel model.UserModel
	Rpc       userclient.User
}

func NewServiceContext(c config.Config) *ServiceContext {
	coon := sqlx.NewMysql(c.Mysql.DataSource)
	db := common.InitGorm(c.Mysql.DataSource)
	db.AutoMigrate(&model.User{})
	return &ServiceContext{
		Config:    c,
		UserModel: model.NewUserModel(coon, c.CacheRedis),
		Rpc:       userclient.NewUser(zrpc.MustNewClient(c.Rpc)),
		DbEngine:  db,
	}
}

就是在ServiceContext结构体里面,把上一步Config里面的字段添加进去,这里我加入了gorm,这个我将在下一章讲到gorm的加入和初始化,这里最后我们要返回是ServiceContext 这个结构体。

Model

在model文件夹下,建一个user.sql文件:

CREATE TABLE `user`
(
    `id`           bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
    `passWord`     varchar(50)     NOT NULL DEFAULT null COMMENT '用户密码,MD5加密',
    `user_Nick`     varchar(100)    NOT NULL DEFAULT NULL COMMENT '用户昵称',
    `user_Face`     varchar(255)    NOT NULL DEFAULT NULL COMMENT '用户头像地址',
    `User_Sex`      tinyint(1)      NOT NULL DEFAULT null COMMENT '用户性别:0男,1女,2保密',
    `user_Email`    varchar(255)    NOT NULL DEFAULT NULL COMMENT '用户邮箱',
    `user_Phone`    varchar(20)     NOT NULL DEFAULT NULL COMMENT '手机号',
    `login_Address` varchar(255)    NOT NULL DEFAULT NULL COMMENT '用户登录IP地址',
    `create_time`  timestamp       NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_time`  timestamp       NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`id`),
    KEY `userPhone` (`user_Phone`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4 COMMENT ='用户表';

然后cd 到mdel,终端输入:goctl model mysql ddl -src user.sql -dir . -c

这个时候你就会看到你model下多了一些文件,我们接下来的进行mysql的操作将在usermodel.go文件里面,注意:usermodel_gen文件最好不要动,因为你后续加入新的业务修改表的时候,再次goctl,usermodel_gen里面的内容会被初始化,你要是之前在这里面写逻辑你就白写了,所以后续是在usermodel.go文件里面添加,下面有例子:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dQ10ehVv-1682646052261)(/Users/liuxian/Pictures/typora图片/image-20230427094743729.png)]

在UserModel这个空接口里面填逻辑,比如我这里就是FindUserby,也是在usermodel里面实现你的逻辑

RPC

首先新建一个user.proto文件:

syntax = "proto3";

package user;

option go_package = "./user";

message SendCodeRep{
  string UserPhone = 1;

}
message RegisterReq{
  string UserPhone = 1;
  string VeCode = 2;
}

message LoginReq{
  string PhoneOrEmail = 1;
  string PassWord = 2;
}
message SendCodeReply{
  string VeCode = 1;

}
message CommonReply{
  int64 Code = 1;
  string Message = 2;
  string Data = 3;
  int64 UserId = 4;
}

message UserInfoReq{
  string UserIdentity = 1;
}

service user{
  rpc SendCode(SendCodeRep) returns (SendCodeReply);
  rpc Register(RegisterReq) returns(CommonReply);
  rpc Login(LoginReq) returns(CommonReply);
  rpc UserInfo(UserInfoReq) returns (CommonReply);

}

这里我写的有点粗糙,我后面改一下,先这样用着,然后cd到rpc下输入:

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

Name: user.rpc
ListenOn: 0.0.0.0:8080
Etcd:
  Hosts:
  - 127.0.0.1:2379
  Key: user.rpc
# mysql配置
Mysql:
  DataSource: root:root@(127.0.0.1:3306)/xian-shop?charset=utf8mb4&parseTime=True&loc=Asia%2FShanghai
# redis 配置
CacheRedis:
  - Host: 127.0.0.1:6379
    Pass:
    Type: node

# redis配置
Redis:
  Host: 127.0.0.1:6379
  Pass:
  DB: 0


# 腾讯云 SMS 配置
Credential:
  SecretId: XXXXXXXX #你自己的
  SecretKey: XXXXXXX #你自己的

这里我们外接腾讯呀SMS服务实现短信验证,我也会在后面的章节介绍

同样,按照api的做法,把config,svc文件配好

config:

package config

import (
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/zrpc"
)

type Config struct {
	zrpc.RpcServerConf
	Mysql struct {
		DataSource string
	}
	CacheRedis cache.CacheConf
	Redis      struct {
		Host string
		Pass string
		DB   int
	}
	Credential struct {
		SecretId  string
		SecretKey string
	}
}

Svc:

package svc

import (
	"XianShop/service/common"
	"XianShop/service/user/model"
	"XianShop/service/user/rpc/internal/config"
	"github.com/redis/go-redis/v9"

	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"gorm.io/gorm"
)

type ServiceContext struct {
	Config    config.Config
	UserModel model.UserModel
	Rdb       *redis.Client
	DbEngine  *gorm.DB
}

func NewServiceContext(c config.Config) *ServiceContext {
	coon := sqlx.NewMysql(c.Mysql.DataSource)
	db := common.InitGorm(c.Mysql.DataSource)
	rdb := common.InitRedis(c.Redis.Host, c.Redis.Pass, c.Redis.DB)
	db.AutoMigrate(&model.User{})
	return &ServiceContext{
		Config:    c,
		UserModel: model.NewUserModel(coon, c.CacheRedis),
		Rdb:       rdb,
		DbEngine:  db,
	}
}

这里我配了redis实现验证码的缓存,也会在后面章节介绍

总结

这一章实现了user服务的api, model,rpc的基础配置,下一章将开始实现gorm,redis,腾讯云SMS,validate校验数据格式,md5加密的配置

感谢

如果你觉得我的文章对你有帮忙,欢迎点赞,关注,star!有问题可以在评论区直接提出来,感谢大家的阅读!🥰🥰🥰🥰🥰🥰

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值