“This is the 11th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”
B station video explanation address
www.bilibili.com/video/BV1h4…
Making the source code
Github.com/CocaineCong…
2. User module
2.1 Database Configuration
- user/conf/conf.ini
File configuration, mysql configuration, service configuration…
[service]
AppMode = debug
HttpPort = :3000
[mysql]
Db = mysql
DbHost = 127.0.0.1
DbPort = 3306
DbUser = root
DbPassWord = root
DbName = todo_list
Copy the code
- user/model/
Load the configuration
func Init(a) {
file, err := ini.Load("./conf/config.ini")
iferr ! =nil {
fmt.Println(Configuration file reading error, please check file path:, err)
}
LoadMysqlData(file)
path := strings.Join([]string{DbUser, ":", DbPassWord, "@tcp(", DbHost, ":", DbPort, "/", DbName, "? charset=utf8&parseTime=true"}, "")
model.Database(path)
}
Copy the code
- user/model/user.go
Defining the database model
type User struct {
gorm.Model
UserName string `gorm:"unique"`
PasswordDigest string
}
Copy the code
- user/model/migration.go
Database model migration
func migration(a) {
Automatic migration mode
DB.Set("gorm:table_options"."charset=utf8mb4").
AutoMigrate(&User{})
}
Copy the code
2.2 ProTO file preparation
- user/services/protos/userModels.proto
Define the proto model of user, note that this must be capitalized!! Otherwise, the back gateway cannot be bound!
syntax="proto3";
package services;
option go_package =". /; protos";
message UserModel{
// @inject_tag: json:"id"
uint32 ID=1;
// @inject_tag: json:"user_name"
string UserName=2;
// @inject_tag: json:"avatar"
string Avatar=3;
// @inject_tag: json:"email"
string Email=4;
// @inject_tag: json:"nickname"
string NickName=5;
// @inject_tag: json:"status"
string Status=6;
// @inject_tag: json:"limit"
uint32 Limit=7;
// @inject_tag: json:"created_at"
int64 CreatedAt=8;
// @inject_tag: json:"updated_at"
int64 UpdatedAt=9;
// @inject_tag: json:"deleted_at"
int64 DeletedAt=10;
}
Copy the code
Execute in the proto directory
protoc --proto_path=. --micro_out=. --go_out=. userModel.proto
Copy the code
- user/services/protos/userService.proto
The UserRequest and UserResponse parameters are defined here
syntax="proto3";
package services;
import "userModels.proto";
option go_package =". /; protos";
message UserRequest{
// @inject_tag: json:"user_name" form:"user_name" uri:"user_name"
string UserName=1;
// @inject_tag: json:"password" form:"password" uri:"password"
string Password=2;
// @inject_tag: json:"password_confirm" form:"password_confirm" uri:"password_confirm"
string PasswordConfirm=3;
}
message UserDetailResponse{
UserModel UserDetail=1;
uint32 Code=2;
}
service UserService{
rpc UserLogin(UserRequest) returns(UserDetailResponse);
rpc UserRegister(UserRequest) returns(UserDetailResponse);
}
Copy the code
Execute in the proto directory
protoc --proto_path=. --micro_out=. --go_out=. userService.proto
Copy the code
Just generate these four files and move toservices
File.
2.3 Implement the service logic of the user module
Define the structure of the user service
//UserService UserService
type UserService struct{}Copy the code
2.3.1 User Registration method
The parameters passed here are the context information, as well as the UserRequest and UserDetailResponse of the Services layer
// UserRegister user registration
func (*UserService) UserRegister(ctx context.Context, req *services.UserRequest, res *services.UserDetailResponse) error {
ifreq.Password ! = req.PasswordConfirm { err := errors.New("Two different passwords entered.")
return err
}
count := 0
if err := model.DB.Model(&model.User{}).Where("user_name=?", req.UserName).Count(&count).Error; err ! =nil {
return err
}
if count > 0 {
err := errors.New("Username already exists")
return err
}
user := model.User{
UserName: req.UserName,
}
// Encrypt the password
iferr := user.SetPassword(req.Password); err ! =nil {
return err
}
// Create a user
iferr := model.DB.Create(&user).Error; err ! =nil {
return err
}
res.UserDetail = BuildUser(user)
return nil
}
Copy the code
2.3.2 Logging In to the Service
Same logic, UserLogin method implemented here, same context, request parameters, response parameters
//UserLogin implements user service interface UserLogin
func (*UserService) UserLogin(ctx context.Context, req *services.UserRequest, res *services.UserDetailResponse) error {
var user model.User
res.Code = 200
if err := model.DB.Where("user_name = ?", req.UserName).First(&user).Error; err ! =nil {
// If no query is found, an error is returned
if gorm.IsRecordNotFoundError(err) {
res.Code = 10003
return nil
}
res.Code = 30001
return nil
}
if user.CheckPassword(req.Password) == false {
res.Code = 10004
return nil
}
res.UserDetail = BuildUser(user)
return nil
}
Copy the code
2.4 Access etCD Service Discovery
- Registered etcd
etcdReg := etcd.NewRegistry(
registry.Addrs("127.0.0.1:2379"),Copy the code
- Get the microservice instance
// 1. Get the microservice instance
microService := micro.NewService(
micro.Name("rpcUserService"), // Set the name of the microservice to be accessed
micro.Address("127.0.0.1:8082"),
micro.Registry(etcdReg),
)
Copy the code
- Initialize the
microService.Init()
Copy the code
- The service registry
Register user services with etCD
_ = services.RegisterUserServiceHandler(microService.Server(), new(core.UserService))
Copy the code
- Start microservices
_ = microService.Run()
Copy the code
Check the etcdhttp://localhost:8080/etcdkeeper/
Whether the module has registration information
At this point, the client’s micro service has been completed, we access the gateway, call the service.