跳过正文
Background Image
  1. Posts/

Go:Web 简单后端搭建步骤

··354 字·2 分钟· loading · loading ·
yuzjing
作者
yuzjing
目录

🌐 项目目标
#

使用 Gin 框架搭建一个简单web服务.

🛠️ 项目结构
#

 1todo-api/
 2├── main.go                 # 入口文件
 3├── routes/
 4│   └── todo_routes.go    # 路由定义
 5├── models/
 6│   └── todo.go           # 数据结构
 7├── middleware/
 8│   └── logging.go        # 自定义中间件
 9├── config/
10│   └── config.go         # 配置管理
11└── go.mod                # Go 模块

📦 安装依赖
#

1go mod init todo-api
2go get -u github.com/gin-gonic/gin
3go get -u github.com/jackc/pgx/v4

🧪 代码示例
#

1. 配置管理(config/config.go
#

1package configimport "github.com/joho/godotenv"func LoadEnv() {
2err := godotenv.Load()
3if err != nil {
4panic("Error loading .env file")
5  }
6}

2. 数据库连接(main.go
#

 1package mainimport (
 2"context"
 3"fmt"
 4"log"
 5"github.com/gin-gonic/gin"
 6"github.com/jackc/pgx/v4"
 7"todo-api/config"
 8"todo-api/routes"
 9)type Todo struct {
10ID    int    `json:"id"`
11Title string `json:"title"`
12}func main() {
13// 1. 加载环境变量
14config.LoadEnv()// 2. 连接 PostgreSQL
15connStr := fmt.Sprintf(
16"postgres://%s:%s@%s:%s/%s?sslmode=disable",
17os.Getenv("DB_USER"),
18os.Getenv("DB_PASSWORD"),
19os.Getenv("DB_HOST"),
20os.Getenv("DB_PORT"),
21os.Getenv("DB_NAME"),
22)conn, err := pgx.Connect(context.Background(), connStr)
23if err != nil {
24log.Fatal("无法连接数据库:", err)
25}
26defer conn.Close(context.Background())// 3. 创建 Gin 应用
27r := gin.Default()// 4. 注册路由
28todoRoutes := routes.TodoRoutes{DB: conn}
29r.POST("/todos", todoRoutes.CreateTodo)
30r.GET("/todos", todoRoutes.GetAllTodos)// 5. 启动服务
31r.Run(":8080")
32}

3. 路由实现(routes/todo_routes.go
#

 1package routesimport (
 2"github.com/gin-gonic/gin"
 3"todo-api/models"
 4)type TodoRoutes struct {
 5DB *pgx.Conn
 6}func (tr *TodoRoutes) CreateTodo(c *gin.Context) {
 7var todo models.Todo
 8if err := c.ShouldBindJSON(&todo); err != nil {
 9c.JSON(400, gin.H{"error": err.Error()})
10return
11}_, err := tr.DB.Exec(context.Background(), "INSERT INTO todos (title) VALUES ($1)", todo.Title)
12if err != nil {
13    c.JSON(500, gin.H{"error": "数据库操作失败"})
14    return
15}
16
17c.JSON(201, gin.H{"message": "成功创建任务"})
18_, err := tr.DB.Exec(context.Background(), "INSERT INTO todos (title) VALUES ($1)", todo.Title)
19if err != nil {
20    c.JSON(500, gin.H{"error": "数据库操作失败"})
21    return
22}
23
24c.JSON(201, gin.H{"message": "成功创建任务"})
25}func (tr *TodoRoutes) GetAllTodos(c *gin.Context) {
26rows, err := tr.DB.Query(context.Background(), "SELECT id, title FROM todos")
27if err != nil {
28c.JSON(500, gin.H{"error": "查询失败"})
29return
30}var todos []models.Todo
31for rows.Next() {
32    var t models.Todo
33    if err := rows.Scan(&t.ID, &t.Title); err != nil {
34        c.JSON(500, gin.H{"error": "解析结果失败"})
35        return
36    }
37    todos = append(todos, t)
38}
39
40c.JSON(200, todos)
41var todos []models.Todo
42for rows.Next() {
43    var t models.Todo
44    if err := rows.Scan(&t.ID, &t.Title); err != nil {
45        c.JSON(500, gin.H{"error": "解析结果失败"})
46        return
47    }
48    todos = append(todos, t)
49}
50
51c.JSON(200, todos)
52}