优秀的编程知识分享平台

网站首页 > 技术文章 正文

4. 使用Go语言编写个人博客 新增用户并使用CURL测试

nanyue 2024-09-09 04:59:09 技术文章 7 ℃

上一节我们完成了数据库连接与User模型相关的代码。本节将实现新增用户相关的代码。最后使用Linux中curl命令测试确认是否能成功写数据库。

以下是修改后的main.go文件

package main

import (
	"xblog/models"
	"xblog/router"
)

func main() {
	models.InitDB()
	router.InitRouter()
}

package main 声明当前代码属于 main 包。main 包是 Go 程序的入口点,程序从 main 包的 main 函数开始执行。

import 语句用于导入其他包的代码。此时,新添加导入 xblog/router 包。

  • xblog/router 包定义了路由配置。

func main() 是 main 包的入口函数。程序从 main 函数开始执行。添加InitRouter函数。

  • router.InitRouter() 函数用于初始化路由配置。

接下来修改models/user.go文件,创建两个函数:CheckUser、CreateUser

// CheckUser 查询用户是否存在
func CheckUser(name string) error {
	var user User

	// DB.First(&user)如果记录未找到,仅返回错误
	err := DB.Select("id").Where("username = ?", name).First(&user).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil // 用户名不存在
		}
		return err // 数据库访问错误
	}
	return errors.New("用户名已存在")
}

// CreateUser 创建新用户
func CreateUser(u *User) error {
	if err := DB.Create(&u).Error; err != nil {
		return err
	}
	return nil
}

CheckUser 的函数,用于检查数据库中是否已存在相同用户名的用户。

var user User 声明一个User类型的变量,用于接收查询结果。

err := DB.Select("id").Where("username = ?", name).First(&user).Error 使用全局数据库连接对象DB来查询用户表。只选择id字段进行查询,使用Where来添加查询条件,确保username与函数参数name相等。First方法会返回查询到的第一条记录,Error属性包含了执行过程中可能出现的错误。接下来我使用if语句判断err,这个错误是否为GORM的ErrRecordNotFound。如果是,说明用户名不存在,返回nil。如果不是,则返回实际的错误,表示数据库访问出现问题。

CreateUser 函数用于创建新用户,接受一个*User类型的参数。

CreateUser 函数中的if语句块 err := DB.Create(&u).Error 调用全局数据库连接对象DB的Create方法来插入新用户。如果发生错误,return err 返回这个错误。如果没有错误发生,return nil 返回nil表示用户创建成功。

新建api/user.go文件,完成如下代码的编写:

package api

import (
	"net/http"
	"xblog/models"

	"github.com/gin-gonic/gin"
)

func UserAdd(c *gin.Context) {
	var u models.User
	// 判断绑定JSON是否成功
	if err := c.ShouldBindJSON(&u); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": err.Error(),
		})
		return
	}

	// 判断用户名是否存在
	if err := models.CheckUser(u.Username); err != nil {
		if err.Error() == "用户名已存在" {
			c.JSON(http.StatusConflict, gin.H{
				"error": err.Error(),
			})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	// 创建用户时的判断
	if err := models.CreateUser(&u); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusCreated, gin.H{
		"data": u,
	})
}

导入部分,程序使用了以下包:

  • net/http 标准库的一个包,被用来处理HTTP请求和响应。
  • xblog/models 这是当前应用的一个模块,用于处理数据模型。
  • github.com/gin-gonic/gin 这是Gin框架的包,用于快速编写web应用。

UserAdd 的函数接受一个 *gin.Context 对象作为参数。这个对象包含了当前HTTP请求的所有信息,并用于发送HTTP响应。

var u models.User 声明一个 models.User 类型的变量 u,这个类型来自前面导入的 xblog/models 包。

接下来使用if err := c.ShouldBindJSON(&u); err != nil 代码尝试将HTTP请求体中的JSON数据绑定(转换)到u变量,即用户模型实例。如果有错误,就会进入条件语句中。如果JSON绑定失败,函数会发送一个400状态码(错误请求)的HTTP响应,并包含错误描述。

if err := models.CheckUser(u.Username); err != nil 然后通过 CheckUser 方法检查u.Username 是否存在于系统中。如果有错误返回,则执行第2个 if 代码块,继续判断如果错误信息是“用户名已存在”,则函数会返回409状态码(冲突)的HTTP响应,同时带上错误描述。

接下来使用if err := models.CreateUser(&u); err != nil语句尝试创建一个用户,如果有错误发生进入条件语句块,如果创建用户时失败,则返回500状态码的HTTP响应并包含错误描述。

c.JSON(http.StatusCreated, gin.H{ "data": u, }) }如果用户创建成功,函数将发送201状态码(已创建)的HTTP响应,并包含创建的用户信息。

UserAdd 函数总体上描述了创建一个新用户的处理流程:接收JSON数据,校验用户名是否已存在,然后创建新用户,并根据操作的结果返回相应的HTTP响应。

新建api/router.go文件,完成UserAdd的路由

package router

import (
	"xblog/api"

	"github.com/gin-gonic/gin"
)

func InitRouter() {
	// 创建默认路由实例
	r := gin.Default()

	// 配置路由
	public := r.Group("api/v1")
	{
		public.POST("user/add", api.UserAdd)
	}
	r.Run(":8000")
}

首先import两个包。它们的作用如下:

  • xblog/api 是当前应用程序中定义的API处理函数所在的包,如 UserAdd 函数。
  • github.com/gin-gonic/gin 是Gin web框架的导入路径,Gin 可用于轻松创建RESTful API接口。

func InitRouter() 定义了一个没有参数也没有返回值的函数,该函数用于设置和初始化路由。

r := gin.Default() 创建了一个Gin默认的路由实例 r,这个实例包含了Logger和Recovery中间件,Logger用于记录日志,Recovery用于捕获可能出现的panic,并返回500服务错误。

public := r.Group("api/v1") 创建路由组 public,这个组包含所有以 "api/v1" 作前缀的路由,可以把一系列相关路由组织在一起。当我们的代码还只有一条路由时就创建分组的原因是能把后续需要认证的路由区分开。

public.POST("user/add", api.UserAdd) 这一行代码定义了一个路由,当HTTP POST请求 "api/v1/user/add" 这个URL时,会调用 api 包中的 UserAdd 函数来处理请求。这相当于一个端点,客户端可以通过这个端点向服务器发送用户添加(注册)的请求。

r.Run(":8000") 启动Gin web服务器并使其监听本机的8000端口。这意味着Gin框架会处理发往该服务器8000端口的所有HTTP请求。

总而言之, InitRouter 函数创建了一个Gin路由实例,设置了一个路由组,里面定义了一个POST方法的路由,并让这个路由与一个处理新增用户请求的函数关联。最后,它启动了一个监听8000端口的HTTP服务器。

好,新增用户的所有代码已经编写完成,让我们运行程序测试一下。

根据上面两张截图可知:我们使用go run main.go成功运行了程序,并使用curl命令测试了新增用户的功能,两次都有预期返回结果。很好,我们再次去数据库查询确认一下。

Tags:

最近发表
标签列表