Go 和 Gin 打造一个带图库功能的随机图片 API?让我们一起走进 Go Web 开发的奇妙世界!


大家好!今天我们要带你们进入一个充满魔法的世界——那就是用 GoGin 来打造一个简单高效的 随机图片 API。是不是听起来有点新奇?嗯,那就让我们一起通过一段代码,揭开这个神秘面纱吧!🎩✨

项目背景

在开发过程中,我们经常会遇到需要随机展示图片的需求。想象一下:你正在开发一个应用,希望用户每次刷新页面时都能看到不同的图片。那么,这个时候就需要一个 “随机图片生成器”,这个 API 的使命就是——每次你请求它时,都给你返回一张图库中的随机图片。至于它们是怎么来的,嘿嘿,那是我们的秘密!🕵️♂️

我们会在这里实现:

  • 图片上传接口,用来上传你自己的图片。
  • 图库管理接口,让你可以动态增删图库。
  • 随机图片接口,让你轻松地从图库中选取一张图片。

技术栈

  • Go:我们选择了 Go 语言,因为它高效、简洁,且在构建 Web 应用时表现得非常出色。
  • Gin:这是一个轻量级的 Web 框架,非常适合做 API 服务,它的性能也让人惊叹。
  • SQLite:为了方便存储图库信息,我们使用了 SQLite,这样既轻便又够用。
  • 文件管理:图片会保存在服务器上,通过文件系统进行管理。

项目结构

为了让大家更好地理解,我们将代码拆分成几个部分,并一步步进行讲解。让我们从整体项目结构开始!

├── controllers
│   ├── image_controller.go      # 控制器:图片相关操作
├── models
│   ├── gallery.go              # 模型:图库数据结构
├── database
│   ├── database.go             # 数据库初始化与操作
├── config
│   ├── cors.go                 # CORS配置
├── main.go                     # 主程序入口
└── images                      # 图片存储目录
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

有了这个结构,接下来的代码讲解会更加清晰!现在,让我们开始进入细节——代码篇!


1. 控制器:管理图片与图库

我们的控制器 image_controller.go 是整个项目的核心,它处理所有与图片和图库相关的请求。控制器的职责包括:上传图片、获取图库、删除图库、获取随机图片等等。

上传图片接口

这是最基础的功能,让我们来看看如何处理图片上传:

// 上传图片
func UploadImage(c *gin.Context) {
	// 获取图库参数,如果没有传则默认使用 "nature"
	gallery := c.DefaultQuery("gallery", "nature")

	// 获取图片文件
	file, _ := c.FormFile("file")
	if file == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未上传文件"})
		return
	}

	// 创建图库目录
	dirPath := fmt.Sprintf("./images/%s", gallery)
	if _, err := os.Stat(dirPath); os.IsNotExist(err) {
		os.MkdirAll(dirPath, os.ModePerm)  // 创建图库目录
	}

	// 保存文件
	filePath := fmt.Sprintf("%s/%s", dirPath, file.Filename)
	err := c.SaveUploadedFile(file, filePath)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "保存文件失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "文件上传成功",
		"file":    filePath,
	})
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.

详细讲解

  • 我们首先通过 c.FormFile("file") 获取上传的文件。
  • 然后,我们根据 图库名称 (gallery 参数) 创建对应的文件夹。如果文件夹不存在,我们使用 os.MkdirAll() 来创建它。
  • 接下来,我们用 c.SaveUploadedFile() 保存文件到指定路径。

看!就是这么简单,上传图片的功能就完成了!让我们大声喊一声“上传成功!”📤


2. 获取指定图库的随机图片

好了,我们上传了图片,现在轮到随机图片功能登场了。🎰

下面的代码将帮助我们从指定的图库中随机选择一张图片:

// 获取指定图库的随机图片
func GetRandomImageByGallery(c *gin.Context) {
	// 获取图库名称
	gallery := c.DefaultQuery("gallery", "nature")

	// 获取图库对应的文件夹路径
	dirPath := fmt.Sprintf("./images/%s", gallery)

	// 检查图库文件夹是否存在
	if _, err := os.Stat(dirPath); os.IsNotExist(err) {
		c.JSON(http.StatusNotFound, gin.H{"error": "图库不存在"})
		return
	}

	// 获取目录下所有文件
	files, err := filepath.Glob(filepath.Join(dirPath, "*"))
	if err != nil || len(files) == 0 {
		c.JSON(http.StatusNotFound, gin.H{"error": "图库中没有图片"})
		return
	}

	// 随机选择一张图片
	rand.Seed(time.Now().Unix())
	randomIndex := rand.Intn(len(files))
	randomImage := files[randomIndex]

	c.JSON(http.StatusOK, gin.H{"image": randomImage})
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

讲解

  • 我们首先通过 gallery 参数获取指定图库的名称。
  • 使用 os.Stat 来检查目录是否存在。如果没有该图库,则返回 404。
  • 通过 filepath.Glob 获取图库中的所有图片文件路径。
  • 最后,我们用 rand.Intn() 从这些文件中随机挑选一张,返回给用户。

这就是获取随机图片的全部逻辑,看起来是不是很酷?🌀


3. 图库增删改查

库的增删改查(CRUD)功能是 Web 应用常见的需求之一,我们需要能够动态地管理图库。下面是如何实现图库的 增、删、改、查 接口。

添加图库接口
// 添加图库
func AddGallery(c *gin.Context) {
	var gallery models.Gallery
	if err := c.ShouldBindJSON(&gallery); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
		return
	}

	// 插入数据库
	if err := database.DB.Create(&gallery).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "添加图库失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "图库添加成功"})
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 说明:通过接收 Gallery 模型的数据,将新图库信息插入到数据库中。
删除图库接口
// 删除图库
func DeleteGallery(c *gin.Context) {
	// 获取图库ID
	var input struct {
		ID uint `json:"id" binding:"required"`
	}
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
		return
	}

	// 查找图库并删除
	var gallery models.Gallery
	if err := database.DB.First(&gallery, input.ID).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "图库不存在"})
		return
	}

	// 删除图库记录
	if err := database.DB.Delete(&gallery).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除图库失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "图库删除成功"})
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.

讲解

  • 我们通过 ShouldBindJSON 获取请求中的 ID
  • 通过 database.DB.First 查找该 ID 的图库,然后删除。

4. 总结与反思

通过这一篇博客,我们一步步实现了一个简单的 随机图片 API,涵盖了图片上传、图库管理和随机选择图片的功能。这个项目的开发过程中,我们用到了 Go 的 Gin 框架SQLite 数据库,以及强大的文件系统管理来保证我们的图片能够灵活管理。

至此,随机图片 API 终于完成了! 你可以通过上传图片,管理图库,并随时通过指定图库获取一张随机图片。感觉自己就像一位神奇的图片巫师!🧙♂️

最后,写代码的过程是充满挑战和乐趣的,尤其是当你看到自己的 API 成功工作时,那种满足感是无可替代的。希望你们在实现这个

项目时能收获到同样的快乐,当然,别忘了常常 庆祝 小小的胜利!🎉


感谢大家阅读,祝你们代码愉快,debug 顺利!


posted @ 2025-02-24 11:17  繁依Fanyi  阅读(8)  评论(0)    收藏  举报  来源