路由
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
文件中注册它们。
启动 HTTP 服务器
通过调用 facades.Route().Run()
在根目录的 main.go
中启动 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("Route run error: %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()
// 创建一个通道来监听操作系统信号
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("Route run error: %v", err)
}
}()
// 监听操作系统信号
go func() {
<-quit
if err := facades.Route().Shutdown(); err != nil {
facades.Log().Errorf("Route shutdown error: %v", err)
}
os.Exit(0)
}()
select {}
路由方法
方法 | 操作 |
---|---|
Group | 分组路由 |
Prefix | 路由前缀 |
ServeHTTP | 测试路由 |
Get | 基本路由 |
Post | 基本路由 |
Put | 基本路由 |
Delete | 基本路由 |
Patch | 基本路由 |
Options | 基本路由 |
Any | 基本路由 |
Resource | 资源路由 |
Static | 文件路由 |
StaticFile | 文件路由 |
StaticFS | 文件路由 |
Middleware | 中间件 |
基本路由
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{}
}
// GET /resource
func (c *ResourceController) Index(ctx http.Context) {}
// GET /resource/{id}
func (c *ResourceController) Show(ctx http.Context) {}
// POST /resource
func (c *ResourceController) Store(ctx http.Context) {}
// PUT /resource/{id}
func (c *ResourceController) Update(ctx http.Context) {}
// DELETE /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)
详情 中间件
回退路由
使用 Fallback
方法,您可以定义一个在没有其他路由匹配传入请求时将执行的路由。
facades.Route().Fallback(func(ctx http.Context) http.Response {
return ctx.Response().String(404, "未找到")
})
速率限制
定义速率限制器
Goravel 包含强大且可自定义的限流服务,您可以使用它来限制给定路由或路由组的流量。 要开始使用,您应该定义满足应用程序需求的限流器配置。 通常,这应该在应用程序的 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 将自动返回一个 HTTP 状态码为 429 的响应。 如果您想定义自己的速率限制响应,可以使用 response 方法:
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 {
// Suppose
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 文档。