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

相关推荐
用户7917286761979 分钟前
在 opencode 中使用 opencode-plugin-loop 插件完全指南
后端
用户31268748772010 分钟前
MyBatis-Plus 动态分表实战:基于 DynamicTableNameInnerInterceptor 的多端数据隔离方案
后端
干到60岁退休的码农32 分钟前
SpringBoot整合Mybatis-plus
spring boot·后端·mybatis
掘金者阿豪34 分钟前
从Oracle迁到金仓,第一个月踩的最大的坑就是它
前端·后端
aramae38 分钟前
C++11:现代C++的里程碑
c语言·开发语言·c++·windows·git·后端
小四的小六42 分钟前
MCP Server 从0到1实战:手写一个让AI调用本地数据库的Tool工具
后端·openai·ai编程
无相求码1 小时前
为什么你的第二个 scanf 还没输入就直接跳过了?C语言输入缓冲区陷阱
c语言·后端
叼馒女友郭芙蓉1 小时前
Function Calling理解
后端
玉宇夕落1 小时前
LangChain RAG Retriever 的学习
后端
用户298698530141 小时前
Python 一键导出 Excel 中的图表和形状为图片
后端·python·excel