Skip to content

Handler & Route

Tầng server/ biến business logic của controller thành các endpoint HTTP. Mỗi domain có một package handler dưới server/<domain>/, từng route handler nằm trong file riêng của nó, và server/route.go kết nối tất cả lên HTTP router. ftkit verify thực thi các quy ước dưới đây.

Package handler

Mỗi domain handler nằm trong server/<domain>/ và chứa file <domain>_impl.go — kiểu implementation cùng với constructor của nó. Constructor được đặt tên New<Domain>API(...) và nhận một slice []core.CoreController để framework có thể inject các controller mà handler phụ thuộc vào.

ftkit verify (verifyHandlers) kiểm tra sự tồn tại của file *_impl.go, constructor New*API(), và rằng constructor nhận controllers []core.CoreController. Nó cũng kiểm tra file impl được đặt tên theo thư mục của nó (ví dụ orders/orders_impl.go).

go
// server/orders/orders_impl.go
package orders

type ordersAPI struct {
    ordersCtrl *orders.OrdersController
}

func NewOrdersAPI(controllers []core.CoreController) *ordersAPI {
    // lấy OrdersController từ slice được inject
    return &ordersAPI{ /* ... */ }
}

File implementation chỉ chứa phần wiring. Các method route handler — những method nhận *fiber.Ctx — không được nằm trong *_impl.go; bộ verifier (verifyNoRouteHandlersInImpl) từ chối bất kỳ method *fiber.Ctx nào tìm thấy ở đó. Chúng thuộc về các file handler riêng (xem mục tiếp theo).

Một handler mỗi file

Mỗi route handler có file riêng, đặt tên {group}.{camelCase}_handler.go, chứa đúng một receiver method. ftkit verify (verifyHandlerSingleFunc) thực thi:

  • Đặt tên — file phải khớp {group}.{operation}_handler.go.
  • Group khớp thư mục{group} phải bằng tên thư mục domain, nên một file trong server/orders/ được đặt tên orders.<operation>_handler.go.
  • Operation là camelCase{operation} phải bắt đầu bằng chữ thường và không chứa dấu gạch dưới hay gạch ngang (ví dụ createOrder, listOrders).
  • Đúng một method — file phải khai báo chính xác một receiver method. Không có method nào là cảnh báo; hai method trở lên là lỗi.
go
// server/orders/orders.createOrder_handler.go
package orders

func (h *ordersAPI) CreateOrder(c *fiber.Ctx) error {
    // parse request, gọi h.ordersCtrl, ghi response
}

Vì file chỉ chứa một method handler, nó cũng không được khai báo bất kỳ struct nào — verifyNoDataStructs đánh dấu lỗi với struct trong file *_handler.go y như với controller.

Route

Định tuyến HTTP được kết nối trong server/route.go thông qua hàm initHTTPHandle(). Bộ verifier (verifyRouteFile) tìm:

  • initHTTPHandle() — hàm đăng ký tất cả các route.
  • API versioning — tiền tố api/v* (ví dụ api/v1).
  • Route group — ít nhất một lời gọi .Group(...) để gom nhóm các endpoint liên quan.
  • Tham chiếu handler — các route gọi handler thông qua server theo dạng s.<Xxx>Handler.<Operation>.
go
// server/route.go
func (s *server) initHTTPHandle() {
    v1 := s.app.Group("/api/v1")

    orders := v1.Group("/orders")
    orders.Post("/", s.OrdersHandler.CreateOrder)
    orders.Get("/", s.OrdersHandler.ListOrders)
}

Để các package handler được đăng ký lúc khởi động, server/server.go phải blank-import package biz (import _ ".../biz"). ftkit verify (verifyServerStructure) kiểm tra blank import này; nếu thiếu nó thì các controller không bao giờ tự đăng ký và handler không có gì để kết nối tới.