goravel
  • README
  • ORM
    • getting-started
    • Migrations
    • Relationships
  • Architecutre Concepts
    • Facades
    • Request Lifecycle
    • Service Container
    • Service Providers
  • Digging Deeper
    • Artisan Console
    • Cache
    • Events
    • File Storage
    • Helpers
    • Mail
    • Mock
    • Package Development
    • Queues
    • Task Scheduling
  • Getting Started
    • Compile
    • Configuration
    • Directory Structure
    • Installation
  • prologue
    • Contribution Guide
    • Excellent Extend Packages
  • security
    • Authentication
    • Authorization
    • Encryption
    • Hashing
  • The Basics
    • Controllers
    • Grpc
    • Logging
    • Middleware
    • HTTP Requests
    • HTTP Response
    • Routing
    • Validation
  • upgrade
    • History Upgrade
    • Upgrading To v1.1 From v1.0
    • Upgrading To v1.10 From v1.9
    • Upgrading To v1.11 From v1.10
    • Upgrading To v1.12 From v1.11
    • Upgrading To v1.2 From v1.1
    • Upgrading To v1.3 From v1.2
    • Upgrading To v1.4 From v1.3
    • Upgrading To v1.5 From v1.4
    • Upgrading To v1.6 From v1.5
    • Upgrading To v1.7 From v1.6
    • Upgrading To v1.8 From v1.7
    • Upgrading To v1.9 From v1.8
  • zh
    • ORM
      • 快速入门
      • 数据库迁移
      • 模型关联
    • 核心架构
      • Facades
      • 请求周期
      • 服务容器
      • 服务提供者
    • 综合话题
      • Artisan 命令行
      • 缓存系统
      • 事件系统
      • 文件存储
      • 辅助函数
      • 发送邮件
      • Mock
      • 扩展包开发
      • 队列
      • 任务调度
    • 入门指南
      • 编译
      • 配置信息
      • 文件夹结构
      • 安装
    • prologue
      • 贡献指南
      • 优秀扩展包
    • security
      • 用户认证
      • 用户授权
      • 加密解密
      • 哈希
    • 基本功能
      • 控制器
      • Grpc
      • 日志
      • HTTP 中间件
      • 请求
      • 响应
      • 路由
      • 表单验证
    • upgrade
      • 历史版本升级
      • 从 v1.0 升级到 v1.1
      • 从 v1.9 升级到 v1.10
      • 从 v1.10 升级到 v1.11
      • 从 v1.11 升级到 v1.12
      • 从 v1.1 升级到 v1.2
      • 从 v1.2 升级到 v1.3
      • 从 v1.3 升级到 v1.4
      • 从 v1.4 升级到 v1.5
      • 从 v1.5 升级到 v1.6
      • 从 v1.6 升级到 v1.7
      • 从 v1.7 升级到 v1.8
      • 从 v1.8 升级到 v1.9
Powered by GitBook
On this page
  • 简介
  • 默认路由文件
  • 启动 HTTP 服务器
  • 启动 HTTPS 服务器
  • 注册中间件
  • 启动服务器
  • 路由方法
  • 基本路由
  • 资源路由
  • 路由分组
  • 路由前缀
  • 文件路由
  • 路由传参
  • 中间件
  • Fallback 路由
  • 速率限制
  • 定义速率限制器
  • 将速率限制器附加到路由
  • 跨域资源共享 (CORS)
  • 测试路由
Edit on GitHub
  1. zh
  2. 基本功能

路由

[[toc]]

简介

Goravel 路由模块可以使用 facades.Route() 进行操作。

默认路由文件

所有路由文件都在 /routes 目录中进行定义。框架默认有一个示例路由 /routes/web.go,其中 func Web() 方法被注册到 app/providers/route_service_provider.go 文件中,以实现路由的绑定。

你可以在 routes 目录下新增路由文件,以进行更细颗粒的管理,然后在 app/providers/route_service_provider.go 文件中进行注册。

启动 HTTP 服务器

在根目录下 main.go 中启动 HTTP 服务器,facades.Route().Run() 将会自动获取 route.host 的配置。

package main

import (
  "github.com/goravel/framework/facades"

  "goravel/bootstrap"
)

func main() {
  //This bootstraps the framework and gets it ready for use.
  bootstrap.Boot()

  //Start http server by facades.Route().
  go func() {
    if err := facades.Route().Run(); err != nil {
      facades.Log().Errorf("Route run error: %v", err)
    }
  }()

  select {}
}

启动 HTTPS 服务器

注册中间件

框架内置了一个通用的中间件,您也可以根据自己需求进行自定义。

// app/http/kernel.go
import "github.com/goravel/framework/http/middleware"

func (kernel *Kernel) Middleware() []http.Middleware {
  return []http.Middleware{
    middleware.Tls(),
  }
}

启动服务器

facades.Route().RunTLS() 将会自动获取 route.tls 的配置:

// main.go
if err := facades.Route().RunTLS(); err != nil {
  facades.Log().Errorf("Route run error: %v", err)
}

您也可以使用 facades.Route().RunTLSWithCert() 方法,自定义 host 与 证书:

// main.go
if err := facades.Route().RunTLSWithCert("127.0.0.1:3000", "ca.pem", "ca.key"); err != nil {
  facades.Log().Errorf("Route run error: %v", err)
}

路由方法

方法
作用

Run

RunTLS

RunTLSWithCert

Group

Prefix

ServeHTTP

Get

Post

Put

Delete

Patch

Options

Any

Resource

Static

StaticFile

StaticFS

Middleware

基本路由

facades.Route().Get("/", func(ctx http.Context) {
  ctx.Response().Json(nethttp.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(route route.Route) {
  route.Get("group/{id}", func(ctx http.Context) {
    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"))

一般情况下,我们无法将文件路由定向到根目录 /,如果您真的想这么做,可以使用如下方式:

// 安装依赖 
go get -u github.com/gin-contrib/static

// 定义中间件 app/http/middleware/static.go,然后将其注册到 app/http/kernel.go
package middleware

import (
  "github.com/gin-contrib/static"

  contractshttp "github.com/goravel/framework/contracts/http"
  frameworkhttp "github.com/goravel/framework/http"
)

func Static() contractshttp.Middleware {
  return func(ctx contractshttp.Context) {
    static.Serve("/", static.LocalFile("./public", false))(ctx.(*frameworkhttp.GinContext).Instance())

    ctx.Request().Next()
  }
}

路由传参

facades.Route().Get("/input/{id}", func(ctx http.Context) {
  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 路由

使用 Fallback 方法,您可以定义一个在没有其他路由匹配传入请求时将执行的路由。

facades.Route().Fallback(func(ctx http.Context) {
  ctx.Response().String(404, "not found")
})

速率限制

定义速率限制器

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 将自动返回一个带有 429 HTTP 状态码的响应。如果你想定义自己的响应,应该由速率限制返回,你可以使用 Response 方法:

facades.RateLimiter().For("global", func(ctx contractshttp.Context) contractshttp.Limit {
  return limit.PerMinute(1000).Response(func(ctx contractshttp.Context) {
    ctx.Response().String(429, "Custom response...")
    return
  })
})

由于速率限制器回调接收传入的 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(100).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 middleware 将速率限制器附加到路由或路由组。路由中间件接受你希望分配给路由的速率限制器的名称:

facades.Route().Middleware(middleware.Throttle("global")).Get("/", func(ctx http.Context) {
  ctx.Response().Json(200, http.Json{
    "Hello": "Goravel",
  })
})

跨域资源共享 (CORS)

Goravel 已默认启用 CORS,详细配置可以到 config/cors.go 文件中进行修改,该功能被作为全局中间件注册在 app/http/kernel.go 中。

测试路由

func TestHttp(t *testing.T) {
  w := httptest.NewRecorder()
  req, err := http.NewRequest("GET", "/users", nil)
  assert.Nil(t, err)
  facades.Route().ServeHTTP(w, req)
  assert.Equal(t, 200, w.Code)
  assert.Equal(t, "1", w.Body.String())
}
Previous响应Next表单验证

Last updated 1 year ago

详见

详见

有关 CORS 和 CORS 标头的更多信息,请参阅 。

请求
中间件
MDN 关于 CORS 的 Web 文档
启动 HTTP 服务器
启动 HTTPS 服务器
启动 HTTPS 服务器
路由分组
路由前缀
测试路由
基本路由
基本路由
基本路由
基本路由
基本路由
基本路由
基本路由
资源路由
文件路由
文件路由
文件路由
中间件