用Golang实现简单的博客系统,核心需要覆盖文章发布、编辑、删除、列表查询、详情查看这几个基础功能,整体可以采用轻量级的gin框架作为Web层,搭配SQLite作为存储数据库,整体架构清晰且容易扩展。

项目初始化与依赖安装
首先新建项目目录,初始化Go模块,然后安装需要的依赖包,gin用于路由处理,gorm用于数据库操作,sqlite驱动用于连接数据库。
// 初始化模块 go mod init blog_system // 安装依赖 go get -u github.com/gin-gonic/gin go get -u gorm.io/gorm go get -u gorm.io/driver/sqlite
数据模型设计
博客系统的核心数据模型是文章,需要包含文章ID、标题、内容、创建时间、更新时间、发布状态这些基础字段,使用gorm定义模型结构。
package model
import (
"time"
"gorm.io/gorm"
)
// Article 文章模型
type Article struct {
ID uint `gorm:"primaryKey" json:"id"`
Title string `gorm:"type:varchar(200);not null" json:"title"`
Content string `gorm:"type:text;not null" json:"content"`
Status int `gorm:"type:int;default:1" json:"status"` // 1草稿 2发布
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
数据库初始化
在项目入口处初始化数据库连接,自动迁移文章模型,确保数据库表结构和模型定义一致。
package main
import (
"blog_system/model"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
var DB *gorm.DB
func initDB() {
var err error
DB, err = gorm.Open(sqlite.Open("blog.db"), &gorm.Config{})
if err != nil {
panic("数据库连接失败: " + err.Error())
}
// 自动迁移模型
err = DB.AutoMigrate(&model.Article{})
if err != nil {
panic("数据表迁移失败: " + err.Error())
}
}
核心接口实现
文章发布接口
接收前端传递的标题、内容、发布状态参数,校验参数合法性后存入数据库,返回创建成功的文章信息。
package handler
import (
"blog_system/model"
"net/http"
"github.com/gin-gonic/gin"
)
func CreateArticle(c *gin.Context) {
var req struct {
Title string `json:"title" binding:"required"`
Content string `json:"content" binding:"required"`
Status int `json:"status" binding:"required,oneof=1 2"`
}
// 参数校验
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误: " + err.Error()})
return
}
// 创建文章
article := model.Article{
Title: req.Title,
Content: req.Content,
Status: req.Status,
}
if err := model.DB.Create(&article).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "文章创建失败"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "文章创建成功", "data": article})
}
文章列表查询接口
支持分页查询,默认返回发布状态的文章,也可以根据状态筛选,返回文章列表和总条数。
func GetArticleList(c *gin.Context) {
page := c.DefaultQuery("page", "1")
pageSize := c.DefaultQuery("page_size", "10")
status := c.Query("status")
var articles []model.Article
var total int64
query := model.DB.Model(&model.Article{})
// 如果传入了状态参数则筛选
if status != "" {
query = query.Where("status = ?", status)
}
// 查询总条数
query.Count(&total)
// 分页查询
offset := (atoi(page) - 1) * atoi(pageSize)
query.Offset(offset).Limit(atoi(pageSize)).Find(&articles)
c.JSON(http.StatusOK, gin.H{
"data": articles,
"total": total,
"page": page,
"page_size": pageSize,
})
}
// 字符串转整数辅助函数
func atoi(s string) int {
num := 0
for _, ch := range s {
if ch >= '0' && ch <= '9' {
num = num*10 + int(ch-'0')
}
}
return num
}
文章编辑与删除接口
编辑接口根据文章ID更新对应的标题、内容、状态,删除接口使用软删除方式,避免数据丢失。
// 编辑文章
func UpdateArticle(c *gin.Context) {
id := c.Param("id")
var req struct {
Title string `json:"title"`
Content string `json:"content"`
Status int `json:"status"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
return
}
var article model.Article
if err := model.DB.First(&article, id).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "文章不存在"})
return
}
// 更新字段
if req.Title != "" {
article.Title = req.Title
}
if req.Content != "" {
article.Content = req.Content
}
if req.Status != 0 {
article.Status = req.Status
}
model.DB.Save(&article)
c.JSON(http.StatusOK, gin.H{"message": "文章更新成功", "data": article})
}
// 删除文章
func DeleteArticle(c *gin.Context) {
id := c.Param("id")
if err := model.DB.Delete(&model.Article{}, id).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "删除失败"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "文章删除成功"})
}
路由配置与项目启动
将所有接口注册到gin路由中,启动服务后就可以测试博客系统的各项功能。
package main
import (
"blog_system/handler"
"github.com/gin-gonic/gin"
)
func main() {
// 初始化数据库
initDB()
// 初始化路由
r := gin.Default()
// 文章相关路由
articleGroup := r.Group("/articles")
{
articleGroup.POST("", handler.CreateArticle)
articleGroup.GET("", handler.GetArticleList)
articleGroup.PUT("/:id", handler.UpdateArticle)
articleGroup.DELETE("/:id", handler.DeleteArticle)
}
// 启动服务
r.Run(":8080")
}
功能测试
启动项目后,可以使用Postman或者curl工具测试接口,比如发布文章的请求示例如下:
curl -X POST http://127.0.0.1:8080/articles
-H "Content-Type: application/json"
-d '{"title":"Golang博客系统实践","content":"这是一篇测试文章","status":2}'
查询文章列表的请求示例:
curl http://127.0.0.1:8080/articles?page=1&page_size=10&status=2
扩展方向
这个简单博客系统实现了核心功能,后续可以扩展用户登录鉴权、文章分类标签、评论功能、前端页面展示等能力,也可以将SQLite替换为MySQL适配更高并发的场景,整体架构不需要做太大调整就可以满足更多需求。