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等)

相关推荐
bagadesu25 分钟前
28.<Spring博客系统⑤(部署的整个过程
java·后端
百锦再28 分钟前
第14章 智能指针
android·java·开发语言·git·rust·go·错误
倚栏听风雨1 小时前
git "base点"详解,顺便解释merge和rebase区别
后端
掘金一周1 小时前
重新思考 weapp-tailwindcss 的未来 | 掘金一周 11.13
前端·人工智能·后端
小生凡一2 小时前
图解|Go语言实现 Agent|LLM+MCP+RAG
开发语言·后端·golang
l0sgAi2 小时前
SpringAI 整合MCP实现联网搜索 (基于tavily)
java·后端
朝新_2 小时前
【统一功能处理】从入门到源码:拦截器学习指南(含适配器模式深度解读)
数据库·后端·mybatis·适配器模式·javaee
q***7482 小时前
私有化部署DeepSeek并SpringBoot集成使用(附UI界面使用教程-支持语音、图片)
spring boot·后端·ui
Java水解2 小时前
Spring WebFlux 核心操作符详解:map、flatMap 与 Mono 常用方法
后端·spring
Java水解2 小时前
MySQL 慢查询 debug:索引没生效的三重陷阱
后端·mysql