路由设置
修改 main.go,为 Book
添加 CRUD 路由:
添加 CRUD 操作
package main
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"literank.com/rest-books/model"
)
// 数据库实例
var db *gorm.DB
func main() {
// 创建 Gin 路由设置器 router
r := gin.Default()
// 初始化数据库
initDB()
// 定义健康端点
r.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
})
})
r.GET("/books", getBooks)
r.GET("/books/:id", getBook)
r.POST("/books", createBook)
r.PUT("/books/:id", updateBook)
r.DELETE("/books/:id", deleteBook)
r.Run(":8080")
}
// 初始化数据库
func initDB() {
// 打开 SQLite 数据库
var err error
db, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// GORM 自动迁移
db.AutoMigrate(&model.Book{})
}
// Get all books
func getBooks(c *gin.Context) {
var books []model.Book
db.Find(&books)
c.JSON(http.StatusOK, books)
}
// Get single book
func getBook(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
var book model.Book
if err := db.First(&book, id).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Record not found"})
return
}
c.JSON(http.StatusOK, book)
}
// Create a new book
func createBook(c *gin.Context) {
var reqBody model.Book
if err := c.ShouldBindJSON(&reqBody); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
db.Create(&reqBody)
c.JSON(http.StatusCreated, reqBody)
}
// Update an existing book
func updateBook(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
var book model.Book
if err := db.First(&book, id).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Record not found"})
return
}
var reqBody model.Book
if err := c.ShouldBindJSON(&reqBody); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
db.Model(&book).Updates(&reqBody)
c.JSON(http.StatusOK, book)
}
// Delete an existing book
func deleteBook(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
var book model.Book
if err := db.First(&book, id).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Record not found"})
return
}
db.Delete(&book)
c.JSON(http.StatusNoContent, nil)
}
此刻,暂使用 SQLite
1 数据库作演示使用。
GORM(gorm.io/gorm
) 表示“Go ORM”,是一个流行的 Golang 对象关系映射库。它提供了一种与数据库交互的便捷方式。
curl 测试
创建一本新图书:
curl -X POST \
http://localhost:8080/books \
-H 'Content-Type: application/json' \
-d '{
"title": "Sample Book",
"author": "John Doe",
"published_at": "2023-01-01T00:00:00Z",
"description": "A sample book description",
"isbn": "1234567890",
"total_pages": 200
}'
应如下响应:
{"id":1,"title":"Sample Book","author":"John Doe","published_at":"2023-01-01T00:00:00Z","description":"A sample book description","isbn":"1234567890","total_pages":200,"created_at":"2023-11-01T00:00:00Z","updated_at":"2023-11-01T00:00:00Z"}
根据 ID 获取一本图书:
curl -X GET http://localhost:8080/books/1
结果:
{
"id": 1,
"title": "Sample Book",
"author": "John Doe",
"published_at": "2023-01-01T00:00:00Z",
"description": "A sample book description",
"isbn": "1234567890",
"total_pages": 200,
"created_at": "2023-11-01T00:00:00Z",
"updated_at": "2023-11-01T00:00:00Z"
}
列出所有图书:
curl -X GET http://localhost:8080/books
结果列表:
[
{
"id": 1,
"title": "Sample Book",
"author": "John Doe",
"published_at": "2023-01-01T00:00:00Z",
"description": "A sample book description",
"isbn": "1234567890",
"total_pages": 200,
"created_at": "2024-02-23T22:19:55.263649+08:00",
"updated_at": "2024-02-23T22:19:55.263649+08:00"
},
{
"id": 2,
"title": "Great Book",
"author": "Rob Smith",
"published_at": "2022-01-01T00:00:00Z",
"description": "Another sample book description",
"isbn": "8334567890",
"total_pages": 3880,
"created_at": "2024-02-23T22:25:55.067976+08:00",
"updated_at": "2024-02-23T22:25:55.067976+08:00"
}
]
更新一本已有的图书:
curl -X PUT \
http://localhost:8080/books/1 \
-H 'Content-Type: application/json' \
-d '{
"title": "Updated Book Title",
"author": "Jane Smith"
}'
结果:
{
"id": 1,
"title": "Updated Book Title",
"author": "Jane Smith",
"published_at": "2023-01-01T00:00:00Z",
"description": "A sample book description",
"isbn": "1234567890",
"total_pages": 200,
"created_at": "2024-02-23T22:19:55.263649+08:00",
"updated_at": "2024-02-23T22:32:55.881294+08:00"
}
删除一本已有的图书:
curl -X DELETE http://localhost:8080/books/1
服务端返回 code 204 以表示成功删除。
此刻 REST API 服务器已经初具雏形。不错!
Footnotes
-
SQLite: https://www.sqlite.org/index.html ↩