从golang-gin-realworld-example-app项目学写httpapi (四)
https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/routers.go
路由定义
package users
import (
"errors"
"net/http"
"github.com/gin-gonic/gin"
"github.com/wangzitian0/golang-gin-starter-kit/common"
)
// 路由函数 用于用户注册、登录请求,注意 参数 *gin.RouterGroup, 用gin的groups router调用
func UsersRegister(router *gin.RouterGroup) {
router.POST("/", UsersRegistration)
router.POST("/login", UsersLogin)
}
// 路由函数 用于用户信息获取、更新请求
func UserRegister(router *gin.RouterGroup) {
router.GET("/", UserRetrieve)
router.PUT("/", UserUpdate)
}
// 路由函数 用于用户简介获取、增加关注、删除关注
// 请求参数变量,使用 :变量名
func ProfileRegister(router *gin.RouterGroup) {
router.GET("/:username", ProfileRetrieve)
router.POST("/:username/follow", ProfileFollow)
router.DELETE("/:username/follow", ProfileUnfollow)
}
// 请求处理函数,用户简介获取,注意 参数 *gin.Context
func ProfileRetrieve(c *gin.Context) {
// 获取请求参数 username
username := c.Param("username")
// 调用模型定义的FindOneUser函数
userModel, err := FindOneUser(&UserModel{Username: username})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("profile", errors.New("Invalid username")))
return
}
// 序列化查询的结果
profileSerializer := ProfileSerializer{c, userModel}
c.JSON(http.StatusOK, gin.H{"profile": profileSerializer.Response()})
}
// 请求处理函数,用户简介选择关注
func ProfileFollow(c *gin.Context) {
username := c.Param("username")
userModel, err := FindOneUser(&UserModel{Username: username})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("profile", errors.New("Invalid username")))
return
}
// 中间件
myUserModel := c.MustGet("my_user_model").(UserModel)
err = myUserModel.following(userModel)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
serializer := ProfileSerializer{c, userModel}
c.JSON(http.StatusOK, gin.H{"profile": serializer.Response()})
}
// 请求处理函数,用户简介取消关注
func ProfileUnfollow(c *gin.Context) {
username := c.Param("username")
userModel, err := FindOneUser(&UserModel{Username: username})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("profile", errors.New("Invalid username")))
return
}
// 中间件
myUserModel := c.MustGet("my_user_model").(UserModel)
err = myUserModel.unFollowing(userModel)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
serializer := ProfileSerializer{c, userModel}
c.JSON(http.StatusOK, gin.H{"profile": serializer.Response()})
}
// 请求处理函数,用户注册
func UsersRegistration(c *gin.Context) {
// 初始化注册验证
userModelValidator := NewUserModelValidator()
if err := userModelValidator.Bind(c); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
return
}
if err := SaveOne(&userModelValidator.userModel); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
// 设置全局中间件 my_user_model
c.Set("my_user_model", userModelValidator.userModel)
serializer := UserSerializer{c}
c.JSON(http.StatusCreated, gin.H{"user": serializer.Response()})
}
// 请求处理函数,用户登录
func UsersLogin(c *gin.Context) {
// 初始化登录验证
loginValidator := NewLoginValidator()
if err := loginValidator.Bind(c); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
return
}
// 验证用户是否存在
userModel, err := FindOneUser(&UserModel{Email: loginValidator.userModel.Email})
if err != nil {
c.JSON(http.StatusForbidden, common.NewError("login", errors.New("Not Registered email or invalid password")))
return
}
// 验证密码是否有效
if userModel.checkPassword(loginValidator.User.Password) != nil {
c.JSON(http.StatusForbidden, common.NewError("login", errors.New("Not Registered email or invalid password")))
return
}
// 更新上下文中的用户id
UpdateContextUserModel(c, userModel.ID)
serializer := UserSerializer{c}
c.JSON(http.StatusOK, gin.H{"user": serializer.Response()})
}
// 请求处理函数,用户信息获取
func UserRetrieve(c *gin.Context) {
// UserSerializer执行中间件
serializer := UserSerializer{c}
c.JSON(http.StatusOK, gin.H{"user": serializer.Response()})
}
// 请求处理函数,用户信息更新
func UserUpdate(c *gin.Context) {
myUserModel := c.MustGet("my_user_model").(UserModel)
userModelValidator := NewUserModelValidatorFillWith(myUserModel)
if err := userModelValidator.Bind(c); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
return
}
userModelValidator.userModel.ID = myUserModel.ID
if err := myUserModel.Update(userModelValidator.userModel); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
// 更新上下文中的用户id
UpdateContextUserModel(c, myUserModel.ID)
serializer := UserSerializer{c}
c.JSON(http.StatusOK, gin.H{"user": serializer.Response()})
}
从golang-gin-realworld-example-app项目学写httpapi (四)的更多相关文章
- 从golang-gin-realworld-example-app项目学写httpapi (八)
https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/common/unit_test.go 单元测试 ...
- 从golang-gin-realworld-example-app项目学写httpapi (七)
https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/hello.go main调用 package ...
- 从golang-gin-realworld-example-app项目学写httpapi (六)
https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/validators.go 验证器 ...
- 从golang-gin-realworld-example-app项目学写httpapi (五)
https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/middlewares.go 中间件 ...
- 从golang-gin-realworld-example-app项目学写httpapi (三)
https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/serializers.go 序列化 ...
- 从golang-gin-realworld-example-app项目学写httpapi (二)
https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/models.go 模型定义 use ...
- 从golang-gin-realworld-example-app项目学写httpapi (一)
https://wangzitian0.github.io/2013/06/29/zero-to-one-1/ https://github.com/gothinkster/golang-gin-re ...
- Golang Gin 项目包依赖管理 godep 使用
Golang Gin 项目包依赖管理 godep 使用 标签(空格分隔): Go 在按照github.com/tools/godep文档go get完包以后,调整项目结构为$GOPATH/src/$P ...
- Golang Gin 项目使用 Swagger
Golang Gin 项目使用 Swagger 标签(空格分隔): Go 首先需要github.com/swaggo/gin-swagger和github.com/swaggo/gin-swagger ...
随机推荐
- 数据库~Mysql里的Explain说明
对于mysql的执行计划可以在select前添加Explain来实现,它可以告诉我们你的语句性能如何. 下面是对explain的具体说明,也都是官方的,以后进行参考. id SELECT识别符.这是S ...
- java线程状态 以及 sheep()、wait()、yield() 区别
前言 最近看到很多人都在讨论多线程的问题,于是写出了这篇博客,希望可以帮到正在学习和使用这块的朋友们,首先我们先看看两个图(两个图都来自其他码农的分享) 这两个图是一样的逻辑,这里一起罗列出来,下 ...
- WPF中使用TextBlock的Inlines属性来完成复杂的文字内容
参考:http://blog.csdn.net/zhangjiyehandsom/article/details/5498845 1. 需求:要在一行内容中显示不同颜色以及粗细不一的字体, 解决办法: ...
- java中,方法可以访问他的类对象的任何私有特性
java中,方法可以访问他的类对象的任何私有特性 读一本书(Core Java for the Impatient)时,发现这个注意,以前的时候没有在意,今天仔细想想发现记忆不深刻.记录一下 下面代码 ...
- 草稿-把vim变成IDE
从昨天下午到现在一直在研究vim,初学者,从vim最基本的命令开始看起的.是通过vimtutor学习的. 看到最后一章的时候,发现原来vimtutor中的知识知识vim中的冰山一角,vim真正的强大之 ...
- CSS选择器详解(二)通用选择器和高级选择器
目录 通用选择器 高级选择器 子选择器 相邻兄弟选择器 属性选择器 通用选择器 通用选择器可以选择页面上的所有元素,并对它们应用样式,用 * 来表示. 语法: * { property1: value ...
- vue之生命周期的一点总结
vue的生命周期的过程提供了我们执行自定义逻辑的机会,好好理解它的生命周期,对我们很有帮助. 一.vue实例的生命周期(vue2.0) 二.生命周期描述:(参考截图) 三.例子 window.vm = ...
- 关于Hall定理的学习
基本定义 \(Hall\) 定理是二分图匹配的相关定理 用于判断二分图是否存在完美匹配 存在完美匹配的二分图即满足最大匹配数为 \(min(|X|,|Y|)\) 的二分图,也就是至少有一边的点全部被匹 ...
- Cannot find type definition file for '.svn'
描述: Ionic项目在执行ionic build --prod过程中,出现如下错误: 看来是.svn文件影响了编译. 解决办法:升级TortoiseSVN版本(https://tortoisesvn ...
- mysql索引对单表查询的影响
索引被用来快速找出在一个列上用一特定值的行.没有索引,MySQL不得不首先以第一条记录开始并然后读完整个表直到它找出相关的行.表越大,花费时间越多. 如果表对于查询的列有一个索引,MySQL能快速到达 ...