文章目錄
1. 編寫路由
2. 注冊路由
3. 注冊接口
3.1 service層
3.2 api層
3.2 serializer
4. 注冊服務
用到的包
github.com/gin-contrib/sessions
github.com/gin-contrib/sessions/cookie
github.com/gin-gonic/gin
建立一個WSGI應用程式執行個體。
r := gin.Default()
設定全局變量store
store := cookie.NewStore([]byte("something-very-secret"))
在路由中使用中間件調用store
r.Use(sessions.Sessions("mysession", store))
分一個基礎路由組
v1 := r.Group("api/v1")
在這個基礎路由編寫使用者注冊路由
v1 := r.Group("api/v1")
{
//使用者操作
v1.POST("user/register", api.UserRegister)
}
在service先建立一個user.go
再在service層上編寫使用者注冊服務的結構體
//UserRegisterService 管理使用者注冊服務
type UserRegisterService struct {
Nickname string `form:"nickname" json:"nickname" binding:"required,min=2,max=10"`
UserName string `form:"user_name" json:"user_name" binding:"required,min=5,max=15"`
Password string `form:"password" json:"password" binding:"required,min=8,max=16"`
}
在service上編寫使用者注冊register方法
func (service *UserRegisterService) Register() {
}
在api層建立user.go
申請一個 UserRegisterService使用者注冊服務對象。
var userRegisterService service.UserRegisterService
但是這個服務我們還沒有寫,先把這個接口寫完,再把這個服務補上。
上下文綁定資料
c.ShouldBind(&userRegisterService)
調用這個服務的register方法
res := userRegisterService.Register()
傳回這個服務的處理結果
c.JSON(200, res)
api 層的使用者注冊服務全部代碼
func UserRegister(c *gin.Context) {
var userRegisterService service.UserRegisterService
//相當于建立了一個UserRegisterService對象
if err := c.ShouldBind(&userRegisterService); err == nil {
res := userRegisterService.Register()
//調用這個對象中的Register方法。
c.JSON(200, res)
} else {
c.JSON(200, ErrorResponse(err))
logging.Info(err)
}
}
建立一個common.go檔案, 進行錯誤的傳回
//傳回錯誤資訊 ErrorResponse
func ErrorResponse(err error) serializer.Response {
if ve, ok := err.(validator.ValidationErrors); ok {
for _, e := range ve {
field := conf.T(fmt.Sprintf("Field.%s", e.Field))
tag := conf.T(fmt.Sprintf("Tag.Valid.%s", e.Tag))
return serializer.Response{
Status: 40001,
Msg: fmt.Sprintf("%s%s", field, tag),
Error: fmt.Sprint(err),
}
}
}
if _, ok := err.(*json.UnmarshalTypeError); ok {
return serializer.Response{
Status: 40001,
Msg: "JSON類型不比對",
Error: fmt.Sprint(err),
}
}
return serializer.Response{
Status: 40001,
Msg: "參數錯誤",
Error: fmt.Sprint(err),
}
}
建立一個基礎的序列化傳回結構體
// Response 基礎序列化器
type Response struct {
Status int `json:"status"`
Data interface{} `json:"data"`
Msg string `json:"msg"`
Error string `json:"error"`
}
接下來我們就可以編寫register()注冊服務了
先對傳過來的使用者名進行驗證,檢視是否已經存在了
model.DB.Model(&model.User{}).Where("user_name=?",service.UserName).Count(&count)
if count == 1 {
code = e.ErrorExistUser
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
再對密碼進行加密
if err := user.SetPassword(service.Password); err != nil {
logging.Info(err)
code = e.ErrorFailEncryption
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
注意: 我們可以直接再model/user.go下編寫密碼加密方法
const (
PassWordCost = 12 //密碼加密難度
Active string = "active" //激活使用者
)
//SetPassword 設定密碼
func (user *User) SetPassword(password string) error {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), PassWordCost)
if err != nil {
return err
}
user.PasswordDigest = string(bytes)
return nil
}
确認無誤之後對使用者進行建立
if err := model.DB.Create(&user).Error; err != nil {
logging.Info(err)
code = e.ErrorDatabase
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
服務層中使用者注冊的完整代碼
func (service *UserRegisterService) Register() serializer.Response {
var user model.User
var count int
code := e.SUCCESS
model.DB.Model(&model.User{}).Where("user_name=?",service.UserName).Count(&count)
if count == 1 {
code = e.ErrorExistUser
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
user = model.User{
Nickname: service.Nickname,
UserName: service.UserName,
Status: model.Active,
}
//加密密碼
if err := user.SetPassword(service.Password); err != nil {
logging.Info(err)
code = e.ErrorFailEncryption
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
user.Avatar = "http://q1.qlogo.cn/g?b=qq&nk=294350394&s=640"
//建立使用者
if err := model.DB.Create(&user).Error; err != nil {
logging.Info(err)
code = e.ErrorDatabase
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
下一章中,我們編寫使用者登入的業務邏輯。