Go Web 开发 Demo【用户登录、注册、验证】(3)https://developer.aliyun.com/article/1534274
添加路由并测试
添加到我们的管理所有路由的文件(routes.go)中:
测试:
6、统一请求返回格式
我们在学习 SpringBoot 项目的时候也进行了请求的统一返回格式:(code,data,other),这里也是一样,为的是简化开发,比如我们前面返回前端需要这样写:
ctx.JSON(200, gin.H{ "code": 200, "msg": "注册成功", })
统一格式后我们只需要写个 200 和 "注册成功" 就可以了。
此外,我们给前端返回的数据还有一些问题:比如把用户的全部信息都返回出去了(包括密码登隐私信息)
6.1、数据传输对象(dto)
创建一个包 dto 并创建 user_dto.go 用来将返回给前端的 user 转换为 userDto:
package dto import ( "com.lyh/goessential/model" ) type UserDto struct { Name string `json:"name"` Phone string `json:"phone"` } // 将 user 转换为 userDto func ToUserDto(user model.User) UserDto { return UserDto{ Name: user.Name, Phone: user.Phone, } }
修改 controller 中的 Info 方法:
func Info(ctx *gin.Context) { // 从上下文中获得用户的信息 user, _ := ctx.Get("user") ctx.JSON(http.StatusOK, gin.H{"code": 200, "data": gin.H{"user": dto.ToUserDto(user.(model.User))}}) }
再次进行用户验证:
可以看到,这次返回的数据没有其它敏感信息。
6.2、封装 HTTP 返回
创建目录 response,并创建 response.go :
package response import ( "github.com/gin-gonic/gin" "net/http" ) // 这里的 code 是我们自定义的业务code func Response(ctx *gin.Context, httpStatus int, code int, data gin.H, msg string) { ctx.JSON(httpStatus, gin.H{"code": code, "date": data, "msg": msg}) } func Success(ctx *gin.Context, data gin.H, msg string) { Response(ctx, http.StatusOK, 200, data, msg) } func Fail(ctx *gin.Context, data gin.H, msg string) { Response(ctx, http.StatusOK, 400, data, msg) }
定义了统一的前端返回类型之后,我们就可以开始修改之前的返回代码了,之前我们的 HTTP 返回都是通过 ctx.JSON(httpStatus,gin.H) 来返回的,现在我们需要都替换为我们自定义的返回格式,比如下面的:
ctx.JSON(http.StatusUnprocessableEntity, gin.H{ "code": 422, "msg": "手机号必须为11位!", })
统一之后就清爽多了,而且不会存在前端拿一些 JSON 的属性却拿不到的情况。
response.Response(ctx, http.StatusUnprocessableEntity, 422, nil, "手机号必须为11位")
7、从文件中读取配置(viper)
上面我们的很多配置信息都是直接定义在代码中的(比如连接数据库需要的参数),这样很不好管理和维护,所以这里我们统一下配置源。
7.1、安装 viper
go get github.com/spf13/viper
如果需要使用旧版本就去 go.mod 取修改版本号重新下载。
7.2、编写配置文件(yml)
在 config 目录下创建 application.yml:
server: port: 1016 datasource: driverName: mysql host: 127.0.0.1 port: 3306 database: go_web username: root password: Yan1029. charset: utf8mb4
7.3、使用 viper 读取配置文件
在 main 方法中添加读取配置文件的函数:
package main import ( "com.lyh/goessential/common" "github.com/gin-gonic/gin" _ "github.com/go-sql-driver/mysql" "github.com/spf13/viper" "os" ) func main() { InitConfig() db := common.InitDB() defer db.Close() engine := gin.Default() engine = CollectRoute(engine) port := viper.GetString("server.port") if port != "" { panic(engine.Run(":" + port)) } panic(engine.Run()) // 默认端口 8080 } func InitConfig() { workDir, _ := os.Getwd() viper.SetConfigName("application") viper.SetConfigType("yml") viper.AddConfigPath(workDir + "/config") err := viper.ReadInConfig() if err != nil { panic(err) } }
修改 databse.go 中的 InitDB 方法:
driverName := viper.GetString("datasource.driverName") host := viper.GetString("datasource.host") port := viper.GetInt("datasource.port") database := viper.GetString("datasource.database") username := viper.GetString("datasource.username") password := viper.GetString("datasource.password") charset := viper.GetString("datasource.charset")
测试
数据库可以查询成功,配置成功。
注意事项
1、gorm 版本问题
最新版 gorm:
使用旧版本的 gorm:
require ( github.com/jinzhu/gorm v1.9.12 )
总结
至此,我大概明白了 Go 语言怎么开发一个 Web 程序,也消除了我的很多疑虑,比如Java一个类就是一个文件,那Go语言怎么对项目进行分层架构等一些简单但又特别重要的内容。
接下来,学学前端,至少了解怎么和后端交互,写一个功能完整的Web程序。