一、前言:为什么选择 Golang 和 Fiber?
- Golang 的优势:天生支持高并发、编译速度快、部署简单,是企业级后端的首选语言之一。
- Fiber 的亮点:基于 Go 语言的轻量级 Web 框架,对标 Express 和 Koa,提供更简洁的 API 设计和极致的性能(底层集成 Fasthttp)。
- 适用场景:API 开发、微服务、实时应用等高并发场景。
二、环境准备
1. 安装 Go 环境
bash
# 下载并安装 Go(以 Linux/macOS 为例)
curl -o- https://raw.githubusercontent.com/golang/install/master/install.sh | bash
# 验证安装
go version
2. 安装 Fiber CLI
bash
go get github.com/gofiber/fiber/v2/cmd/fiber
3. 创建新项目
arduino
fiber new hello-world
cd hello-world
三、核心代码解析:从零构建一个 API
1.main.go
入门示例
go
package main
import (
"log"
"github.com/gofiber/fiber/v2"
)
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, Fiber!")
})
log.Fatal(app.Listen(":3000"))
}
- 启动命令 :
go run main.go
- 访问效果 :浏览器输入
http://localhost:3000
即可见到 "Hello, Fiber!"。
2. 路由与参数
go
app.Get("/user/:id", func(c *fiber.Ctx) error {
id := c.Params("id")
return c.JSON(fiber.Map{
"message": "User ID is " + id,
})
})
3. 中间件使用(日志记录)
go
func Logger(c *fiber.Ctx) error {
log.Println("Request:", c.Request().URL.Path)
return c.Next()
}
app.Use(Logger)
4. 数据库集成(以 SQLite 为例)
go
import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
)
func initDB() *sql.DB {
db, err := sql.Open("sqlite3", "./test.db")
if err != nil {
log.Fatal(err)
}
return db
}
// 创建表
db.Exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
四、Fiber 的性能优势
指标 | Fiber | Gin | Echo |
---|---|---|---|
微秒级响应 | ✅ | ✅ | ✅ |
内存占用 | 更低 | 中等 | 较高 |
路由匹配速度 | 极快 | 快 | 中等 |
五、实例代码
1. 项目结构调整
csharp
hello-world/
├── cmd/ # 可执行文件入口(可选)
├── internal/ # 业务逻辑层
│ ├── config/ # 配置文件(数据库连接等)
│ ├── handlers/ # 路由处理函数
│ ├── models/ # 数据模型定义
│ └── services/ # 业务逻辑服务层
├── main.go # 入口文件
└── go.mod # Go模块依赖
2. 初始化数据库
(1) 创建 ****config/db.go
go
package config
import (
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
)
var DB *sql.DB
func InitDB() {
var err error
DB, err = sql.Open("sqlite3", "./blog.db")
if err != nil {
fmt.Printf("Failed to connect to database: %v\n", err)
return
}
// 执行迁移脚本
_, err = DB.Exec(`
CREATE TABLE posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
body TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
`)
if err != nil {
fmt.Printf("Failed to create table: %v\n", err)
return
}
// 插入测试数据
_, err = DB.Exec("INSERT INTO posts (title, body) VALUES ('Hello World', 'This is my first post!')")
if err != nil {
fmt.Printf("Failed to insert seed data: %v\n", err)
return
}
}
(2) 在 main.go
中初始化数据库
go
func main() {
config.InitDB()
defer config.DB.Close()
app := fiber.New()
// ... 注册路由
}
3. 定义数据模型
internal/models/post.go
go
package models
type Post struct {
ID int `json:"id"`
Title string `json:"title"`
Body string `json:"body"`
CreatedAt time.Time `json:"created_at"`
}
4. 编写业务逻辑服务层
internal/services/post_service.go
go
package services
import (
"errors"
"time"
"hello-world/internal/models"
"hello-world/internal/config"
)
var ErrPostNotFound = errors.New("post not found")
func GetAllPosts() ([]models.Post, error) {
rows, err := config.DB.Query("SELECT id, title, body, created_at FROM posts")
if err != nil {
return nil, err
}
defer rows.Close()
var posts []models.Post
for rows.Next() {
var p models.Post
err := rows.Scan(&p.ID, &p.Title, &p.Body, &p.CreatedAt)
if err != nil {
return nil, err
}
posts = append(posts, p)
}
return posts, nil
}
func GetPostByID(id int) (*models.Post, error) {
row := config.DB.QueryRow("SELECT id, title, body, created_at FROM posts WHERE id = ?", id)
var p models.Post
err := row.Scan(&p.ID, &p.Title, &p.Body, &p.CreatedAt)
if err == sql.ErrNoRows {
return nil, ErrPostNotFound
}
return &p, err
}
func CreatePost(title, body string) (*models.Post, error) {
res, err := config.DB.Exec(
"INSERT INTO posts (title, body) VALUES (?, ?)",
title,
body,
)
if err != nil {
return nil, err
}
id, err := res.LastInsertId()
if err != nil {
return nil, err
}
return &models.Post{
ID: int(id),
Title: title,
Body: body,
CreatedAt: time.Now(),
}, nil
}
func UpdatePost(id int, title, body string) (*models.Post, error) {
row := config.DB.Exec(
"UPDATE posts SET title = ?, body = ? WHERE id = ?",
title,
body,
id,
)
if err := row.Error; err != nil {
return nil, err
}
return GetPostByID(id)
}
func DeletePost(id int) error {
_, err := config.DB.Exec("DELETE FROM posts WHERE id = ?", id)
return err
}
5. 实现路由和处理函数
internal/handlers/post_handler.go
go
package handlers
import (
"errors"
"net/http"
"github.com/gofiber/fiber/v2"
"hello-world/internal/services"
"hello-world/internal/models"
)
var ErrPostNotFound = errors.New("post not found")
// GetPosts 获取所有文章
func GetPosts(c *fiber.Ctx) error {
posts, err := services.GetAllPosts()
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(posts)
}
// GetPost 获取单篇文章
func GetPost(c *fiber.Ctx) error {
id := c.Params("id")
post, err := services.GetPostByID(id)
if err == ErrPostNotFound {
return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "Post not found"})
}
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(post)
}
// CreatePost 创建新文章
func CreatePost(c *fiber.Ctx) error {
var post models.Post
if err := c.BodyParser(&post); err != nil {
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request"})
}
createdPost, err := services.CreatePost(post.Title, post.Body)
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.Status(http.StatusCreated).JSON(createdPost)
}
// UpdatePost 更新文章
func UpdatePost(c *fiber.Ctx) error {
id := c.Params("id")
var post models.Post
if err := c.BodyParser(&post); err != nil {
return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request"})
}
updatedPost, err := services.UpdatePost(id, post.Title, post.Body)
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(updatedPost)
}
// DeletePost 删除文章
func DeletePost(c *fiber.Ctx) error {
id := c.Params("id")
err := services.DeletePost(id)
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.SendString("Post deleted successfully")
}
6. 注册路由
main.go
go
package main
import (
"log"
"github.com/gofiber/fiber/v2"
"hello-world/internal/handlers"
)
func main() {
config.InitDB()
defer config.DB.Close()
app := fiber.New()
// 路由组:/api/v1
apiV1 := app.Group("/api/v1")
{
apiV1.Get("/posts", handlers.GetPosts) // GET /api/v1/posts
apiV1.Get("/posts/:id", handlers.GetPost) // GET /api/v1/posts/:id
apiV1.Post("/posts", handlers.CreatePost) // POST /api/v1/posts
apiV1.Put("/posts/:id", handlers.UpdatePost) // PUT /api/v1/posts/:id
apiV1.Delete("/posts/:id", handlers.DeletePost)// DELETE /api/v1/posts/:id
}
log.Fatal(app.Listen(":3000"))
}
7. 测试 API
(1) 使用 Postman 或 cURL 测试
shellscript
# 创建文章
curl -X POST -H "Content-Type: application/json" -d '{"title": "My First Post", "body": "Hello Fiber!"}' http://localhost:3000/api/v1/posts
# 获取所有文章
curl http://localhost:3000/api/v1/posts
# 获取单篇文章
curl http://localhost:3000/api/v1/posts/1
# 更新文章
curl -X PUT -H "Content-Type: application/json" -d '{"title": "Updated Post", "body": "Body content"}' http://localhost:3000/api/v1/posts/1
# 删除文章
curl -X DELETE http://localhost:3000/api/v1/posts/1
8. 添加中间件(JWT 认证)
(1) 安装 JWT 包
shellscript
go get github.com/gofiber/fiber/v2/middleware/jwt
(2) 生成密钥和配置
go
// config/jwt.go
package config
import "github.com/gofiber/fiber/v2/middleware/jwt"
var JWTMiddleware = jwt.New(jwt.Config{
SigningKey: []byte("your-secret-key"),
})
(3) 保护路由
go
// main.go
func main() {
// ...
protectedApi := apiV1.Group("/protected")
{
protectedApi.Get("/posts", handlers.GetProtectedPosts) // 需要 JWT 认证
}
// 全局中间件
app.Use(config.JWTMiddleware)
}
(4) 处理受保护的路由
go
// handlers/post_handler.go
func GetProtectedPosts(c *fiber.Ctx) error {
// 用户已通过 JWT 认证
return c.JSON(fiber.Map{"message": "This is a protected route"})
}
9. 部署到云平台(Docker 示例)
(1) 创建 ****Dockerfile
docker
# 使用官方 Golang 镜像作为基础镜像
FROM golang:1.20-alpine
# 设置工作目录
WORKDIR /app
# 复制 Go 模块依赖文件
COPY go.mod go.sum ./
# 下载依赖
RUN go mod download
# 复制源代码
COPY . .
# 构建应用
RUN go build -o main .
# 暴露端口
EXPOSE 3000
# 启动容器
CMD ["./main"]
(2) 创建 ****docker-compose.yml
yaml
version: '3'
services:
web:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
(3) 运行 Docker
shellscript
docker-compose up --build
10. 总结
通过以上步骤,你已经完成了一个包含以下功能的博客 API:
- 完整的 CRUD 操作
- SQLite 数据库集成
- JWT 身份验证保护
- Docker 部署支持
下一步学习方向:
- 添加分页和过滤功能
- 实现文件上传(使用 Fiber 的
multipart
中间件) - 集成 Redis 缓存高频访问数据
- 使用 Swagger 自动生成 API 文档