User registration
Get data/bind data
- Type of data transferred from the front end:
-
Form form: The data is form data
-
Ajax: Data is in JSON format. So this is — Request Payload
-
- The default postForm() method can only fetch the data passed by the form form.
- In the form of Request Payload, you need to use Data binding to obtain the transmitted data.
ctx.Bind()
Bind data to objects.
-- web/main.goAdd r1. POST ("/users", controller.PostRet)
-- web/controller/user.goTo add, implement// Send the registration information
func PostRet(ctx *gin.Context) {
/* mobile := ctx.PostForm("mobile") pwd := ctx.PostForm("password") sms_code := ctx.PostForm("sms_code") fmt.Println("m = ", mobile, "pwd = ", pwd, "sms_code = ",sms_code) */
// Get data
var regData struct {
Mobile string `json:"mobile"`
PassWord string `json:"password"`
SmsCode string `json:"sms_code"`
}
ctx.Bind(®Data)
fmt.Println("The obtained data is :", regData)
}
Copy the code
Micro server
-
Modify the password book — proto file
syntax = "proto3"; package go.micro.srv.user; service User { rpc SendSms(Request) returns (Response) {}; rpc Register(RegRequest) returns (Response) {}; } message Request { string phone = 1; string imgCode = 2; string uuid = 3; } message RegRequest { string mobile = 1; string password = 2; string smsCode = 3; } message Response { string errno = 1; string errmsg = 2; } Copy the code
-
Make Generates the xxx.micro. Go file
-
Modify the handler/user. Go
// Add method func (e *User) Register(ctx context.Context, req *user.RegRequest, rsp *user.Response) error { return nil } Copy the code
-
You need to manipulate the MySQL database and copy web/model/model.go to the microservice project.
-
In the service/user/model/modelFunc. Go add validation message authentication code function
// CheckSmsCode Indicates the VERIFICATION code of the SMS func CheckSmsCode(mobile, smsCode string) bool { / / connect to redis conn := RedisPool.Get() defer conn.Close() // Query data code, err := redis.String(conn.Do("get", mobile+"_code")) iferr ! =nil { fmt.Println("Redis query error:", err) return false } return smsCode == code } Copy the code
-
Service/user/model/modelFunc. Go, add function SaveUserInfo, realize the user registration information, write the MySQL database
// SaveUserInfo stores user information to the user table func SaveUserInfo(mobile, password string) error { var newUser User // If the mobile phone number does not exist, register a new user if GlobalConn.Where("mobile = ?", mobile).Find(&newUser).RecordNotFound() { newUser.Name = mobile newUser.Mobile = mobile // Use MD5 to encrypt password m5 := md5.New() m5.Write([]byte(password)) pwdHash := hex.EncodeToString(m5.Sum(nil)) newUser.Password_hash = pwdHash return GlobalConn.Create(&newUser).Error } // If the mobile phone number already exists, the registration fails return errors.New("Mobile number already exists")}Copy the code
-
Complete the Register function implementation
// Register User registration func (e *User) Register(ctx context.Context, req *user.RegRequest, rsp *user.Response) error { // Verification code - Obtain the verification code from Redis for comparison result := model.CheckSmsCode(req.Mobile, req.SmsCode) // There was a problem getting the captcha service result = true if result { // The verification code is successfully compared // Store user information to mysql database err := model.SaveUserInfo(req.Mobile, req.Password) iferr ! =nil { fmt.Println("Error storing user information:", err) rsp.Errno = utils.RECODE_DBERR rsp.Errmsg = utils.RecodeText(utils.RECODE_DBERR) } else { rsp.Errno = utils.RECODE_OK rsp.Errmsg = utils.RecodeText(utils.RECODE_OK) } } else { // Verification code comparison failed fmt.Println("Verification code comparison error") rsp.Errno = utils.RECODE_DATAERR rsp.Errmsg = utils.RecodeText(utils.RECODE_DATAERR) } return nil } Copy the code
Web side
-
Copy the password book — proto
-
Create a web/utils/utils. Go file and wrap the function to implement the initial Consul client code
// Initialize the micro func InitMicro(a) micro.Service { // Initialize the client consulReg := consul.NewRegistry() return micro.NewService( micro.Registry(consulReg), ) } Copy the code
-
Implement the PostRet function in Web/Controller /user.go
// PostRet sends the registration information func PostRet(ctx *gin.Context) { // Get data var regData struct { Mobile string `json:"mobile"` Password string `json:"password"` SmsCode string `json:"sms_code"` } ctx.Bind(®Data) // Call the remote function microClient := userMicro.NewUserService("go.micro.srv.user", client.DefaultClient) resp, err := microClient.Register(context.TODO(), &userMicro.RegRequest{Mobile: regData.Mobile, Password: regData.Password, SmsCode: regData.SmsCode}) iferr ! =nil { fmt.Println("Failed to call remote function Register:", err) return } // Send it to the browser ctx.JSON(http.StatusOK, resp) } Copy the code
Get geographic information
The interface definition
#Request:
method: GET
url:api/v1. 0/areas #data: no input data #Response #"errno": "0"."errmsg":"OK"."data": [{"aid": 1."aname": "Dongcheng District"},
{"aid": 2."aname": "West Side"},
{"aid": 3."aname": "Tongzhou District"},
{"aid": 4."aname": "Shunyi District"}]
/ /...} # register failed: {"errno": "400x"./ / status code
"errmsg":"Status error message"
}
Copy the code
Business flow chart
Importing SQL Scripts
- Save home.sql to Linux
- Log in to the MySQL database. Select database:
use search_house;
- Run the script file to insert data into the table.
source /Users/yaxuan/home.sql
Web side
-
In web/main.go, add the route and set the callback.
r1.GET("/areas", controller.GetArea) Copy the code
-
In web/ Controller /use.go, add the GetArea() function.
func GetArea(ctx *gin.Context){}Copy the code
-
Get data from the database, improve the user experience of the common method: first check the cache, cache does not check MySQL, write redis cache.
// Get the location information func GetArea(ctx *gin.Context) { // Get data from MySQL. var areas []model.Area model.GlobalConn.Find(&areas) // Write the data to redis. conn := model.RedisPool.Get() conn.Do("set"."areaData", areas) // Store the areas array directly into Redis resp := make(map[string]interface{}) resp["errno"] = "0" resp["errmsg"] = utils.RecodeText(utils.RECODE_OK) resp["data"] = areas ctx.JSON(http.StatusOK, resp) } Copy the code
Consider: Store data to Conn. Do(“set”, “areaData”, areas) in Redis as above for future data retrieval using Do! Hard to get! There is no corresponding reply helper function for type assertion. Select a new way to store redis: convert data to JOSN byte stream storage.
// GetArea gets the location information func GetArea(ctx *gin.Context) { // Get data from Redis first conn := model.RedisPool.Get() areaData, _ := redis.Bytes(conn.Do("get"."areaData")) var areas []model.Area if len(areaData) == 0 { // No data in redis // Get data from mysql model.GlobalConn.Find(&areas) // Write the data to redis -- store the serialized JSON string of the structure areaBuf, _ := json.Marshal(areas) conn.Do("set"."areaData", areaBuf) } else { // There is data in redis json.Unmarshal(areaData, &areas) } resp := make(map[string]interface{}) resp["errno"] = utils.RECODE_OK resp["errmsg"] = utils.RecodeText(utils.RECODE_OK) resp["data"] = areas ctx.JSON(http.StatusOK, resp) } Copy the code