路由
概述
Goravel 路由模組可以使用 facades.Route()
進行操作。
HTTP 驅動
Goravel 預設使用 gin 作為 HTTP 驅動。 要使用其他驅動器,請在 config/http.go
中配置它們。 官方預設支持 gin 和 fiber。
驅動 | 鏈接 |
---|---|
Gin | https://github.com/goravel/gin |
Fiber | https://github.com/goravel/fiber |
預設路由檔案
要定義路由檔案,只需導航至 /routes
目錄。 默認情況下,框架使用位於 /routes/web.go
的範例路由。 要建立路由綁定,func Web()
方法在 app/providers/route_service_provider.go
檔案中註冊。
如果你需要更精確的管理,可以在 /routes
目錄下新增路由檔案,並在 app/providers/route_service_provider.go
檔案中註冊。
獲取路由列表
使用 route:list
命令來查看路由列表:
./artisan route:list
啟動 HTTP 伺服器
在根目錄的 main.go
中呼叫 facades.Route().Run()
來啟動 HTTP 伺服器。 這將自動獲取 route.host
配置。
package main
import (
"github.com/goravel/framework/facades"
"goravel/bootstrap"
)
func main() {
// 這會初始化框架並準備使用。
bootstrap.Boot()
// 通過 facades.Route() 啟動 http 伺服器。
go func() {
if err := facades.Route().Run(); err != nil {
facades.Log().Errorf("路由運行錯誤: %v", err)
}
}()
select {}
}
啟動 HTTPS 伺服器
在使用 HTTPS 之前,請完成 config/http.go
中的 http.tls
配置,facades.Route().RunTLS()
方法將根據相關配置啟動 HTTPS 伺服器。
// main.go
if err := facades.Route().RunTLS(); err != nil {
facades.Log().Errorf("路由運行錯誤: %v", err)
}
你也可以使用 facades.Route().RunTLSWithCert()
方法來自定義主機和證書。
// main.go
if err := facades.Route().RunTLSWithCert("127.0.0.1:3000", "ca.pem", "ca.key"); err != nil {
facades.Log().Errorf("路由運行錯誤: %v", err)
}
關閉 HTTP/HTTPS 伺服器
你可以透過呼叫 Shutdown
方法優雅的關閉 HTTP/HTTPS 伺服器,該方法將等待所有請求處理完後再關閉。
// main.go
bootstrap.Boot()
// 創建一個通道來監聽 OS 信號
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
// 通過 facades.Route() 啟動 http 伺服器。
go func() {
if err := facades.Route().Run(); err != nil {
facades.Log().Errorf("路由運行錯誤: %v", err)
}
}()
// 監聽 OS 信號
go func() {
<-quit
if err := facades.Route().Shutdown(); err != nil {
facades.Log().Errorf("路由關閉錯誤: %v", err)
}
os.Exit(0)
}()
select {}
路由方法
方法名 | 操作 |
---|---|
分組 | 群組路由 |
前綴 | 路由前綴 |
ServeHTTP | 測試路由 |
獲取 | 基本路由 |
Post | 基本路由 |
放 | 基本路由 |
刪除 | 基本路由 |
補丁 | 基本路由 |
選項 | 基本路由 |
任何 | 基本路由 |
資源 | 資源路由 |
靜態 | 文件路由 |
靜態檔案 | 文件路由 |
靜態文件系統 | 文件路由 |
中介軟體 | 中間件 |
獲取路由 | 獲取所有路由 |
名稱 | 設定路由名稱 |
資訊 | 獲取路由資訊 |
基本路由
facades.Route().Get("/", func(ctx http.Context) http.Response {
return ctx.Response().Json(http.StatusOK, http.Json{
"Hello": "Goravel",
})
})
facades.Route().Post("/", userController.Show)
facades.Route().Put("/", userController.Show)
facades.Route().Delete("/", userController.Show)
facades.Route().Patch("/", userController.Show)
facades.Route().Options("/", userController.Show)
facades.Route().Any("/", userController.Show)
資源路由
import "github.com/goravel/framework/contracts/http"
resourceController := NewResourceController()
facades.Route().Resource("/resource", resourceController)
type ResourceController struct{}
func NewResourceController () *ResourceController {
return &ResourceController{}
}
// 獲取 /resource
func (c *ResourceController) Index(ctx http.Context) {}
// 獲取 /resource/{id}
func (c *ResourceController) Show(ctx http.Context) {}
// 發送 /resource
func (c *ResourceController) Store(ctx http.Context) {}
// 更新 /resource/{id}
func (c *ResourceController) Update(ctx http.Context) {}
// 刪除 /resource/{id}
func (c *ResourceController) Destroy(ctx http.Context) {}
路由分組
facades.Route().Group(func(router route.Router) {
router.Get("group/{id}", func(ctx http.Context) http.Response {
return ctx.Response().Success().String(ctx.Request().Query("id", "1"))
})
})
路由前綴
facades.Route().Prefix("users").Get("/", userController.Show)
文件路由
import "net/http"
facades.Route().Static("static", "./public")
facades.Route().StaticFile("static-file", "./public/logo.png")
facades.Route().StaticFS("static-fs", http.Dir("./public"))
路由參數
facades.Route().Get("/input/{id}", func(ctx http.Context) http.Response {
return ctx.Response().Success().Json(http.Json{
"id": ctx.Request().Input("id"),
})
})
詳見請求
中介軟體
import "github.com/goravel/framework/http/middleware"
facades.Route().Middleware(middleware.Cors()).Get("users", userController.Show)
詳見中間件
獲取所有路由
routes := facades.Route().GetRoutes()
設定路由名稱
facades.Route().Get("users", userController.Index).Name("users.index")
獲取路由資訊
route := facades.Route().Info("users.index")
Fallback 路由
使用 Fallback
方法,你可以定義一個在沒有其他路由匹配傳入請求時將執行的路由。
facades.Route().Fallback(func(ctx http.Context) http.Response {
return ctx.Response().String(404, "未找到")
})
速率限制
定義速率限制器
Goravel 包含強大且可自訂的速率限制服務,你可以利用這些服務來限制給定路由或一組路由的流量。 首先,你應該定義滿足應用需求的速率限制器配置。 通常,這應在應用的 app/providers/route_service_provider.go
檔案的 configureRateLimiting
方法中完成。 要開始,您應該定義滿足您應用需求的速率限制器配置。 通常,這應該在您應用的 app/providers/route_service_provider.go
類別的 configureRateLimiting
方法內完成。
速率限制器是使用 facades.RateLimiter()
的 For
方法來定義的。 For
方法接受速率限制器名稱和返回應用於指派給速率限制器的路由的限制配置的閉包。 速率限制器名稱可以是您希望的任何字串:
import (
contractshttp "github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"github.com/goravel/framework/http/limit"
)
func (receiver *RouteServiceProvider) configureRateLimiting() {
facades.RateLimiter().For("global", func(ctx contractshttp.Context) contractshttp.Limit {
return limit.PerMinute(1000)
})
}
如果傳入的請求超過指定的速率限制,Goravel 將自動返回一個帶有 429 HTTP 狀態碼的響應。 如果你想定義自己的響應以由速率限制返回,你可以使用響應方法:
facades.RateLimiter().For("global", func(ctx http.Context) http.Limit {
return limit.PerMinute(1000).Response(func(ctx http.Context) {
ctx.Request().AbortWithStatus(http.StatusTooManyRequests)
})
})
由於速率限制器回調接收傳入的 HTTP 請求實例,你可以根據傳入的請求或經過身份驗證的用戶動態構建適當的速率限制:
facades.RateLimiter().For("global", func(ctx contractshttp.Context) contractshttp.Limit {
// 假設
if is_vip() {
return limit.PerMinute(100)
}
return nil
})
分段速率限制
有時你可能希望按某些任意值分段速率限制。 例如,你可能希望允許用戶每分鐘每個 IP 地址訪問給定路由 100 次。 為了實現這一點,你可以在構建速率限制時使用 By
方法:
facades.RateLimiter().For("global", func(ctx contractshttp.Context) contractshttp.Limit {
if is_vip() {
return limit.PerMinute(100).By(ctx.Request().Ip())
}
return nil
})
為了使用另一個示例來說明此功能,我們可以將每個經過身份驗證的用戶 ID 的路由訪問限制為每分鐘 100 次,或者對於訪客,每個 IP 地址每分鐘訪問 10 次:
facades.RateLimiter().For("global", func(ctx contractshttp.Context) contractshttp.Limit {
if userID != 0 {
return limit.PerMinute(100).By(userID)
}
return limit.PerMinute(10).By(ctx.Request().Ip())
})
多個速率限制
如果需要,你可以返回一個速率限制數組以進行特定的速率限制器配置。 每個速率限制將根據它們在數組中的排列順序進行評估:
facades.RateLimiter().ForWithLimits("login", func(ctx contractshttp.Context) []contractshttp.Limit {
return []contractshttp.Limit{
limit.PerMinute(500),
limit.PerMinute(100).By(ctx.Request().Ip()),
}
})
將速率限制器附加到路由
速率限制器可以通過使用 throttle 中介附件附加到路由或路由組。 throttle 中介接受你希望分配給路由的速率限制器的名稱:
import github.com/goravel/framework/http/middleware
facades.Route().Middleware(middleware.Throttle("global")).Get("/", func(ctx http.Context) http.Response {
return ctx.Response().Json(200, http.Json{
"Hello": "Goravel",
})
})
跨域資源共享 (CORS)
Goravel 已預設啟用 CORS,詳細配置可以到 config/cors.go
文件中進行修改。
有關 CORS 和 CORS 標頭的更多信息,請參閱 MDN 關於 CORS 的 Web 文檔。