Go语言实战案例:用Gin实现图书管理接口

在 Web API 开发中,最常见的场景之一就是构建 增删改查(CRUD) 接口。

本篇我们将用 Gin 框架 来实现一个简单的图书管理系统 API,数据会存储在内存中(方便演示),但结构设计可方便以后替换为数据库。


一、功能目标

我们要实现以下接口:

    1. 获取所有图书 GET /books
    1. 根据ID获取图书 GET /books/:id
    1. 添加图书 POST /books
    1. 更新图书 PUT /books/:id
    1. 删除图书 DELETE /books/:id

二、项目初始化

确保你已安装 Go 1.18+ 和 Gin:

arduino 复制代码
go get -u github.com/gin-gonic/gin

三、代码实现

go 复制代码
package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
    "strconv"
)

// 图书结构体
type Book struct {
    ID     int    `json:"id"`
    Title  string `json:"title"`
    Author string `json:"author"`
}

var books = []Book{
    {ID: 1, Title: "Go语言实战", Author: "张三"},
    {ID: 2, Title: "Gin框架入门", Author: "李四"},
}

// 获取所有图书
func getBooks(c *gin.Context) {
    c.JSON(http.StatusOK, books)
}

// 根据ID获取图书
func getBookByID(c *gin.Context) {
    idStr := c.Param("id")
    id, _ := strconv.Atoi(idStr)

    for _, book := range books {
        if book.ID == id {
            c.JSON(http.StatusOK, book)
            return
        }
    }
    c.JSON(http.StatusNotFound, gin.H{"error": "图书不存在"})
}

// 添加图书
func addBook(c *gin.Context) {
    var newBook Book
    if err := c.ShouldBindJSON(&newBook); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    // 模拟自增ID
    newBook.ID = len(books) + 1
    books = append(books, newBook)

    c.JSON(http.StatusCreated, newBook)
}

// 更新图书
func updateBook(c *gin.Context) {
    idStr := c.Param("id")
    id, _ := strconv.Atoi(idStr)

    var updateData Book
    if err := c.ShouldBindJSON(&updateData); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    for i, book := range books {
        if book.ID == id {
            books[i].Title = updateData.Title
            books[i].Author = updateData.Author
            c.JSON(http.StatusOK, books[i])
            return
        }
    }
    c.JSON(http.StatusNotFound, gin.H{"error": "图书不存在"})
}

// 删除图书
func deleteBook(c *gin.Context) {
    idStr := c.Param("id")
    id, _ := strconv.Atoi(idStr)

    for i, book := range books {
        if book.ID == id {
            books = append(books[:i], books[i+1:]...)
            c.JSON(http.StatusOK, gin.H{"message": "删除成功"})
            return
        }
    }
    c.JSON(http.StatusNotFound, gin.H{"error": "图书不存在"})
}

func main() {
    r := gin.Default()

    r.GET("/books", getBooks)
    r.GET("/books/:id", getBookByID)
    r.POST("/books", addBook)
    r.PUT("/books/:id", updateBook)
    r.DELETE("/books/:id", deleteBook)

    r.Run(":8080")
}

四、运行与测试

运行服务:

go 复制代码
go run main.go

1. 获取所有图书

bash 复制代码
curl http://localhost:8080/books

2. 获取单本图书

bash 复制代码
curl http://localhost:8080/books/1

3. 添加图书

json 复制代码
curl -X POST http://localhost:8080/books \
  -H "Content-Type: application/json" \
  -d '{"title":"Go Web编程","author":"王五"}'

4. 更新图书

json 复制代码
curl -X PUT http://localhost:8080/books/1 \
  -H "Content-Type: application/json" \
  -d '{"title":"Go语言进阶","author":"张三改"}'

5. 删除图书

bash 复制代码
curl -X DELETE http://localhost:8080/books/2

五、总结

  • • 使用 Gin 可以非常轻松地构建 RESTful API
  • • 路由映射到不同的处理函数
  • • JSON 参数解析只需 ShouldBindJSON
  • • 后续可以把 books 切片替换为数据库(MySQL、PostgreSQL、MongoDB等)

相关推荐
RestCloud7 分钟前
MongoDB到关系型数据库:JSON字段如何高效转换?
数据库·mysql·mongodb
Eoch7732 分钟前
HashMap夺命十连问,你能撑到第几轮?
java·后端
每天进步一点_JL32 分钟前
🔥 一个 synchronized 背后,JVM 到底做了什么?
后端
SamDeepThinking1 小时前
有了 AI IDE 之后,为什么还还要 CLI?
后端·ai编程·cursor
yinke小琪1 小时前
线程池七宗罪:你以为的优化其实是在埋雷
java·后端·面试
我不是混子1 小时前
Spring Boot启动时的小助手:ApplicationRunner和CommandLineRunner
java·后端
用户723905105691 小时前
Java并发编程原理精讲
后端
在钱塘江1 小时前
Elasticsearch 快速入门 - Python版本
后端·python·elasticsearch
道可到1 小时前
Java 面试通关笔记 01|拆箱与装箱:你真的理解了吗?
后端·面试
C++chaofan2 小时前
通过Selenium实现网页截图来生成应用封面
java·spring boot·后端·selenium·测试工具·编程·截图