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).
// 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 trongserver/orders/được đặt tênorders.<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.
// 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>.
// 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.