如果你现在要在项目里新增一片“订单快线区”,可以按这个节奏搭:
cmd/
server/
main.go
internal/
app/
app.go
http/
middleware/
auth.go
errors.go
routes/
health.go
orders.go
dto/
order.go
service/
order_service.go
repo/
order_repo.go核心入口可以像这样:
package app
import (
"errors"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/logger"
recoverer "github.com/gofiber/fiber/v3/middleware/recover"
"github.com/gofiber/fiber/v3/middleware/requestid"
)
type structValidator struct {
validate *validator.Validate
}
func (v *structValidator) Validate(out any) error {
return v.validate.Struct(out)
}
func New() *fiber.App {
app := fiber.New(fiber.Config{
StructValidator: &structValidator{validate: validator.New()},
ErrorHandler: func(c fiber.Ctx, err error) error {
code := fiber.StatusInternalServerError
var e *fiber.Error
if errors.As(err, &e) {
code = e.Code
}
return c.Status(code).JSON(fiber.Map{
"code": code,
"message": err.Error(),
})
},
})
app.Use(requestid.New())
app.Use(logger.New())
app.Use(recoverer.New())
app.Get("/health", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"status": "ok"})
})
api := app.Group("/api")
v1 := api.Group("/v1")
v1.Get("/orders/:id", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{
"id": c.Params("id"),
})
})
v1.Post("/orders", func(c fiber.Ctx) error {
type CreateOrderReq struct {
ProductID string `json:"productId" validate:"required"`
Quantity int `json:"quantity" validate:"required,gte=1"`
}
req := new(CreateOrderReq)
if err := c.Bind().Body(req); err != nil {
return err
}
return c.Status(fiber.StatusCreated).JSON(fiber.Map{
"message": "created",
"data": req,
})
})
return app
}这份骨架体现了 Fiber 项目最值得坚持的几条纪律:
- 入口层只管接请求和回响应
Bind + Validate先把输入卡干净ErrorHandler做统一事故口径- 中间件链统一管理横切逻辑
- 业务逻辑别全塞进 handler