httprouter

package module
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2025 License: Apache-2.0 Imports: 6 Imported by: 0

README

HttpRouter Coverage Status Docs

HttpRouter is a lightweight high performance HTTP request router (also called multiplexer or just mux for short) for Go.

In contrast to the default mux of Go's net/http package, this router supports variables in the routing pattern and matches against the request method. It also scales better.

The router is optimized for high performance and a small memory footprint. It scales well even with very long paths and a large number of routes. A compressing dynamic trie (radix tree) structure is used for efficient matching.

Features

Only explicit matches: With other routers, like http.ServeMux, a requested URL path could match multiple patterns. Therefore they have some awkward pattern priority rules, like longest match or first registered, first matched. By design of this router, a request can only match exactly one or no route. As a result, there are also no unintended matches, which makes it great for SEO and improves the user experience.

Stop caring about trailing slashes: Choose the URL style you like, the router automatically redirects the client if a trailing slash is missing or if there is one extra. Of course it only does so, if the new path has a handler. If you don't like it, you can turn off this behavior.

Path auto-correction: Besides detecting the missing or additional trailing slash at no extra cost, the router can also fix wrong cases and remove superfluous path elements (like ../ or //). Is CAPTAIN CAPS LOCK one of your users? HttpRouter can help him by making a case-insensitive look-up and redirecting him to the correct URL.

Parameters in your routing pattern: Stop parsing the requested URL path, just give the path segment a name and the router delivers the dynamic value to you. Because of the design of the router, path parameters are very cheap.

Zero Garbage: The matching and dispatching process generates zero bytes of garbage. The only heap allocations that are made are building the slice of the key-value pairs for path parameters, and building new context and request objects (the latter only in the standard Handler/HandlerFunc API). In the 3-argument API, if the request path contains no parameters not a single heap allocation is necessary.

Best Performance: Benchmarks speak for themselves. See below for technical details of the implementation.

No more server crashes: You can set a Panic handler to deal with panics occurring during handling a HTTP request. The router then recovers and lets the PanicHandler log what happened and deliver a nice error page.

Perfect for APIs: The router design encourages to build sensible, hierarchical RESTful APIs. Moreover it has built-in native support for OPTIONS requests and 405 Method Not Allowed replies.

Of course you can also set custom NotFound and MethodNotAllowed handlers and serve static files.

Usage

This is just a quick introduction, view the Docs for details.

$ go get github.com/julienschmidt/httprouter

and use it, like in this trivial example:

package main

import (
    "fmt"
    "net/http"
    "log"

    "github.com/julienschmidt/httprouter"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    fmt.Fprint(w, "Welcome!\n")
}

func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}

func main() {
    router := httprouter.New()
    router.GET("/", Index)
    router.GET("/hello/:name", Hello)

    log.Fatal(http.ListenAndServe(":8080", router))
}
Named parameters

As you can see, :name is a named parameter. The values are accessible via httprouter.Params, which is just a slice of httprouter.Params. You can get the value of a parameter either by its index in the slice, or by using the ByName(name) method: :name can be retrieved by ByName("name").

When using a http.Handler (using router.Handler or http.HandlerFunc) instead of HttpRouter's handle API using a 3rd function parameter, the named parameters are stored in the request.Context. See more below under Why doesn't this work with http.Handler?.

Named parameters only match a single path segment:

Pattern: /user/:user

 /user/gordon              match
 /user/you                 match
 /user/gordon/profile      no match
 /user/                    no match

Note: Since this router has only explicit matches, you can not register static routes and parameters for the same path segment. For example you can not register the patterns /user/new and /user/:user for the same request method at the same time. The routing of different request methods is independent from each other.

Catch-All parameters

The second type are catch-all parameters and have the form *name. Like the name suggests, they match everything. Therefore they must always be at the end of the pattern:

Pattern: /src/*filepath

 /src/                     match
 /src/somefile.go          match
 /src/subdir/somefile.go   match

How does it work?

The router relies on a tree structure which makes heavy use of common prefixes, it is basically a compact prefix tree (or just Radix tree). Nodes with a common prefix also share a common parent. Here is a short example what the routing tree for the GET request method could look like:

Priority   Path             Handle
9          \                *<1>
3          ├s               nil
2          |├earch\         *<2>
1          |└upport\        *<3>
2          ├blog\           *<4>
1          |    └:post      nil
1          |         └\     *<5>
2          ├about-us\       *<6>
1          |        └team\  *<7>
1          └contact\        *<8>

Every *<num> represents the memory address of a handler function (a pointer). If you follow a path trough the tree from the root to the leaf, you get the complete route path, e.g \blog\:post\, where :post is just a placeholder (parameter) for an actual post name. Unlike hash-maps, a tree structure also allows us to use dynamic parts like the :post parameter, since we actually match against the routing patterns instead of just comparing hashes. As benchmarks show, this works very well and efficient.

Since URL paths have a hierarchical structure and make use only of a limited set of characters (byte values), it is very likely that there are a lot of common prefixes. This allows us to easily reduce the routing into ever smaller problems. Moreover the router manages a separate tree for every request method. For one thing it is more space efficient than holding a method->handle map in every single node, it also allows us to greatly reduce the routing problem before even starting the look-up in the prefix-tree.

For even better scalability, the child nodes on each tree level are ordered by priority, where the priority is just the number of handles registered in sub nodes (children, grandchildren, and so on..). This helps in two ways:

  1. Nodes which are part of the most routing paths are evaluated first. This helps to make as much routes as possible to be reachable as fast as possible.
  2. It is some sort of cost compensation. The longest reachable path (highest cost) can always be evaluated first. The following scheme visualizes the tree structure. Nodes are evaluated from top to bottom and from left to right.
├------------
├---------
├-----
├----
├--
├--
└-

Why doesn't this work with http.Handler?

It does! The router itself implements the http.Handler interface. Moreover the router provides convenient adapters for http.Handlers and http.HandlerFuncs which allows them to be used as a httprouter.Handle when registering a route.

Named parameters can be accessed request.Context:

func Hello(w http.ResponseWriter, r *http.Request) {
    params := httprouter.ParamsFromContext(r.Context())

    fmt.Fprintf(w, "hello, %s!\n", params.ByName("name"))
}

Alternatively, one can also use params := r.Context().Value(httprouter.ParamsKey) instead of the helper function.

Just try it out for yourself, the usage of HttpRouter is very straightforward. The package is compact and minimalistic, but also probably one of the easiest routers to set up.

Automatic OPTIONS responses and CORS

One might wish to modify automatic responses to OPTIONS requests, e.g. to support CORS preflight requests or to set other headers. This can be achieved using the Router.GlobalOPTIONS handler:

router.GlobalOPTIONS = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    if r.Header.Get("Access-Control-Request-Method") != "" {
        // Set CORS headers
        header := w.Header()
        header.Set("Access-Control-Allow-Methods", header.Get("Allow"))
        header.Set("Access-Control-Allow-Origin", "*")
    }

    // Adjust status code to 204
    w.WriteHeader(http.StatusNoContent)
})

Where can I find Middleware X?

This package just provides a very efficient request router with a few extra features. The router is just a http.Handler, you can chain any http.Handler compatible middleware before the router, for example the Gorilla handlers. Or you could just write your own, it's very easy!

Alternatively, you could try a web framework based on HttpRouter.

Multi-domain / Sub-domains

Here is a quick example: Does your server serve multiple domains / hosts? You want to use sub-domains? Define a router per host!

// We need an object that implements the http.Handler interface.
// Therefore we need a type for which we implement the ServeHTTP method.
// We just use a map here, in which we map host names (with port) to http.Handlers
type HostSwitch map[string]http.Handler

// Implement the ServeHTTP method on our new type
func (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// Check if a http.Handler is registered for the given host.
	// If yes, use it to handle the request.
	if handler := hs[r.Host]; handler != nil {
		handler.ServeHTTP(w, r)
	} else {
		// Handle host names for which no handler is registered
		http.Error(w, "Forbidden", 403) // Or Redirect?
	}
}

func main() {
	// Initialize a router as usual
	router := httprouter.New()
	router.GET("/", Index)
	router.GET("/hello/:name", Hello)

	// Make a new HostSwitch and insert the router (our http handler)
	// for example.com and port 12345
	hs := make(HostSwitch)
	hs["example.com:12345"] = router

	// Use the HostSwitch to listen and serve on port 12345
	log.Fatal(http.ListenAndServe(":12345", hs))
}
Basic Authentication

Another quick example: Basic Authentication (RFC 2617) for handles:

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/julienschmidt/httprouter"
)

func BasicAuth(h httprouter.Handle, requiredUser, requiredPassword string) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		// Get the Basic Authentication credentials
		user, password, hasAuth := r.BasicAuth()

		if hasAuth && user == requiredUser && password == requiredPassword {
			// Delegate request to the given handle
			h(w, r, ps)
		} else {
			// Request Basic Authentication otherwise
			w.Header().Set("WWW-Authenticate", "Basic realm=Restricted")
			http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
		}
	}
}

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprint(w, "Not protected!\n")
}

func Protected(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprint(w, "Protected!\n")
}

func main() {
	user := "gordon"
	pass := "secret!"

	router := httprouter.New()
	router.GET("/", Index)
	router.GET("/protected/", BasicAuth(Protected, user, pass))

	log.Fatal(http.ListenAndServe(":8080", router))
}

Chaining with the NotFound handler

NOTE: It might be required to set Router.HandleMethodNotAllowed to false to avoid problems.

You can use another http.Handler, for example another router, to handle requests which could not be matched by this router by using the Router.NotFound handler. This allows chaining.

Static files

The NotFound handler can for example be used to serve static files from the root path / (like an index.html file along with other assets):

// Serve static files from the ./public directory
router.NotFound = http.FileServer(http.Dir("public"))

But this approach sidesteps the strict core rules of this router to avoid routing problems. A cleaner approach is to use a distinct sub-path for serving files, like /static/*filepath or /files/*filepath.

Web Frameworks based on HttpRouter

If the HttpRouter is a bit too minimalistic for you, you might try one of the following more high-level 3rd-party web frameworks building upon the HttpRouter package:

  • Ace: Blazing fast Go Web Framework
  • api2go: A JSON API Implementation for Go
  • Gin: Features a martini-like API with much better performance
  • Goat: A minimalistic REST API server in Go
  • goMiddlewareChain: An express.js-like-middleware-chain
  • Hikaru: Supports standalone and Google AppEngine
  • Hitch: Hitch ties httprouter, httpcontext, and middleware up in a bow
  • httpway: Simple middleware extension with context for httprouter and a server with gracefully shutdown support
  • intake: intake is a minimal http framework with enphasis on middleware groups
  • Jett: A lightweight framework with subrouters, graceful shutdown and middleware at all levels.
  • kami: A tiny web framework using x/net/context
  • Medeina: Inspired by Ruby's Roda and Cuba
  • nchi: provides a chi-like framework using nject for flexibility and ease-of-use
  • Neko: A lightweight web application framework for Golang
  • pbgo: pbgo is a mini RPC/REST framework based on Protobuf
  • River: River is a simple and lightweight REST server
  • siesta: Composable HTTP handlers with contexts
  • xmux: xmux is a httprouter fork on top of xhandler (net/context aware)

Documentation

Overview

Copyright 2013 Julien Schmidt. All rights reserved. 使用本源代码受 BSD 风格许可协议的约束,该协议可在 LICENSE.BASE 文件中找到。 Copyright 2025 WJQSERVER, WJQSERVER-STUDIO. All rights reserved. 使用本源代码受 Apache 2.0许可协议的约束,该协议可在 LICENSE 文件中找到。 Package httprouter 是一个基于 trie 树的高性能 HTTP 请求路由器。

一个简单的例子是:

package main

import (
    "context"
    "fmt"
    "github.com/julienschmidt/httprouter"
    "log"
    "net/http"
    "time"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    fmt.Fprint(w, "Welcome!\n")
}

func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    // 通过 r.Context() 获取上下文
    ctx := r.Context()
    select {
    case <-ctx.Done():
        // 客户端断开连接或请求被取消
        log.Println("Client disconnected for /hello/:name")
        return
    default:
        // 继续正常处理
        fmt.Fprintf(w, "hello, %s! (ctx available)\n", ps.ByName("name"))
    }
}

func LongProcess(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    ctx := r.Context() // 获取请求上下文
    log.Printf("Starting long process for %s...\n", ps.ByName("task"))

    select {
    case <-time.After(10 * time.Second): // 模拟耗时操作
        fmt.Fprintf(w, "Task %s completed!\n", ps.ByName("task"))
        log.Printf("Task %s completed normally.\n", ps.ByName("task"))
    case <-ctx.Done(): // 监听客户端断开或请求取消
        // 如果 ctx.Done() 被关闭,意味着客户端断开连接或服务器取消了请求 (例如超时)
        // 这里的 err 会给出原因,例如 context.Canceled 或 context.DeadlineExceeded
        err := ctx.Err()
        log.Printf("Long process for %s cancelled/client disconnected: %v\n", ps.ByName("task"), err)
        // 可以在这里进行一些清理工作
        // 注意:此时可能无法再向 ResponseWriter 写入数据,因为连接可能已经关闭
    }
}

func AnyHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    fmt.Fprintf(w, "Handled by ANY for path %s, method %s\n", r.URL.Path, r.Method)
}

func main() {
    router := httprouter.New()
    router.GET("/", Index)
    router.GET("/hello/:name", Hello)
    router.GET("/long/:task", LongProcess)

    // 使用 Any 方法
    router.ANY("/anypath", AnyHandler)
    router.ANY("/anypath/:param", AnyHandler)

    // 路由组示例
    adminGroup := router.Group("/admin")
    adminGroup.GET("/dashboard", Index)
    adminGroup.ANY("/settings", AnyHandler)

    log.Println("Server starting on :8080...")
    log.Fatal(http.ListenAndServe(":8080", router))
}

... (其余注释保持不变) ...

Index

Constants

This section is empty.

Variables

DefaultMethodsForAny 定义了 ANY 方法将注册的 HTTP 方法列表

View Source
var MatchedRoutePathParam = "$matchedRoutePath"

MatchedRoutePathParam 是存储匹配路由路径的 Param 名称, 如果设置了 Router.SaveMatchedRoutePath。

View Source
var ParamsKey = paramsKey{}

ParamsKey 是 URL 参数存储在请求上下文中的键。 用户可以使用 `req.Context().Value(httprouter.ParamsKey)` 来获取参数, 但通常直接使用 Handle 函数签名中的 `Params` 参数更方便。

Functions

func CleanPath

func CleanPath(p string) string

CleanPath is the URL version of path.Clean, it returns a canonical URL path for p, eliminating . and .. elements.

The following rules are applied iteratively until no further processing can be done:

  1. Replace multiple slashes with a single slash.
  2. Eliminate each . path name element (the current directory).
  3. Eliminate each inner .. path name element (the parent directory) along with the non-.. element that precedes it.
  4. Eliminate .. elements that begin a rooted path: that is, replace "/.." by "/" at the beginning of a path.

If the result of this process is an empty string, "/" is returned

Types

type ErrorHandlerFunc added in v0.0.4

type ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, statusCode int)

ErrorHandlerFunc 定义了处理HTTP错误的函数的签名。 它接收状态码以及标准的ResponseWriter和Request。

type Group

type Group struct {
	// contains filtered or unexported fields
}

Group 代表一个路由组,具有一个路径前缀。

func (*Group) ANY added in v0.0.3

func (g *Group) ANY(path string, handle Handle)

ANY 为组内路径注册一个处理所有 DefaultMethodsForAny 中定义的方法的 Handler。

func (*Group) DELETE

func (g *Group) DELETE(relativePath string, handle Handle)

func (*Group) Delete

func (g *Group) Delete(relativePath string, handle Handle)

func (*Group) GET

func (g *Group) GET(relativePath string, handle Handle)

func (*Group) Get

func (g *Group) Get(relativePath string, handle Handle)

func (*Group) HEAD

func (g *Group) HEAD(relativePath string, handle Handle)

func (*Group) Handle

func (g *Group) Handle(method, relativePath string, handle Handle)

Handle 是 Group 的 router.Handle 的快捷方式

func (*Group) Handler

func (g *Group) Handler(method, relativePath string, handler http.Handler)

Handler 是 Group 的 router.Handler 的快捷方式

func (*Group) HandlerFunc

func (g *Group) HandlerFunc(method, path string, handler http.HandlerFunc)

HandlerFunc 是 Group 的 router.HandlerFunc 的快捷方式

func (*Group) Head

func (g *Group) Head(relativePath string, handle Handle)

func (*Group) OPTIONS

func (g *Group) OPTIONS(relativePath string, handle Handle)

func (*Group) Options

func (g *Group) Options(relativePath string, handle Handle)

func (*Group) PATCH

func (g *Group) PATCH(relativePath string, handle Handle)

func (*Group) POST

func (g *Group) POST(relativePath string, handle Handle)

func (*Group) PUT

func (g *Group) PUT(relativePath string, handle Handle)

func (*Group) Patch

func (g *Group) Patch(relativePath string, handle Handle)

func (*Group) Post

func (g *Group) Post(relativePath string, handle Handle)

func (*Group) Put

func (g *Group) Put(relativePath string, handle Handle)

func (*Group) ServeFiles

func (g *Group) ServeFiles(relativePath string, root http.FileSystem)

ServeFiles 是 Group 的 router.ServeFiles 的快捷方式

func (*Group) Use

func (g *Group) Use(middleware ...Middleware)

type Handle

type Handle func(http.ResponseWriter, *http.Request, Params)

Handle 是一个可以注册到路由以处理 HTTP 请求的函数。 类似于 http.HandlerFunc,但有第三个参数用于通配符(路径变量)的值。 **重要提示**: 可以通过 `r.Context()` 在此函数内部获取 `context.Context`。 该上下文可用于感知客户端断开连接 (`<-r.Context().Done()`) 或传递请求范围的值。

type Middleware

type Middleware func(http.Handler) http.Handler

Middleware 是一个可以封装 http.Handler 的函数。 典型的用法是在调用链中执行预处理或后处理操作。

type Param

type Param struct {
	Key   string
	Value string
}

Param 是一个单独的 URL 参数,由一个键和一个值组成。

type Params

type Params []Param

Params 是一个 Param 切片,由路由器返回。 切片是有序的,第一个 URL 参数也是第一个切片值。 因此通过索引读取值是安全的。

func ParamsFromContext

func ParamsFromContext(ctx context.Context) Params

ParamsFromContext 从请求上下文中提取 URL 参数, 如果不存在则返回 nil。

func (Params) ByName

func (ps Params) ByName(name string) string

ByName 返回键匹配给定名称的第一个 Param 的值。 如果没有找到匹配的 Param,则返回空字符串。

func (Params) MatchedRoutePath

func (ps Params) MatchedRoutePath() string

MatchedRoutePath 检索匹配路由的路径。 必须在添加相应的处理程序时启用 Router.SaveMatchedRoutePath, 否则此函数始终返回空字符串。

type RecoveryHandlerFunc

type RecoveryHandlerFunc func(http.ResponseWriter, *http.Request, interface{})

RecoveryHandlerFunc 定义了处理从 panic 中恢复的函数的签名。

type Router

type Router struct {

	// Middlewares 是应用于所有请求的全局中间件列表。
	// 中间件按照在 Use 方法中添加的顺序执行。
	Middlewares []Middleware

	// 如果启用,在调用处理程序之前将匹配的路由路径添加到 http.Request 上下文。
	// 匹配的路由路径只添加到启用此选项时注册的路由处理程序。
	SaveMatchedRoutePath bool

	// 如果当前路由无法匹配,但存在带(或不带)尾部斜杠的路径处理程序,则启用自动重定向。
	// 例如,如果请求 /foo/ 但只存在 /foo 的路由,则客户端将被重定向到 /foo,
	// 对于 GET 请求使用 http 状态码 301,对于所有其他请求方法使用 308。
	RedirectTrailingSlash bool

	// 如果启用,路由器会尝试修复当前请求路径,如果没有为其注册处理程序。
	// 首先,会移除诸如 ../ 或 // 等多余的路径元素。
	// 然后,路由器会对清理后的路径进行不区分大小写的查找。
	// 如果找到了该路由的处理程序,路由器会以状态码 301(GET 请求)和 308(所有其他请求方法)
	// 重定向到修正后的路径。
	// 例如,/FOO 和 /..//Foo 可以被重定向到 /foo。
	// RedirectTrailingSlash 与此选项无关。
	RedirectFixedPath bool

	// 如果启用,当当前请求无法路由时,路由器会检查是否允许使用其他方法。
	// 如果是这种情况,请求会以“不允许使用的方法”和 HTTP 状态码 405 进行响应。
	// 如果没有允许的其他方法,则将请求委托给 NotFound 处理程序。
	HandleMethodNotAllowed bool

	// 如果启用,路由器会自动回复 OPTIONS 请求。
	// 自定义 OPTIONS 处理程序优先于自动回复。
	HandleOPTIONS bool

	// 一个可选的 http.Handler,在自动 OPTIONS 请求时调用。
	// 只有当 HandleOPTIONS 为 true 且未设置特定路径的 OPTIONS 处理程序时,才会调用此处理程序。
	// 在调用处理程序之前会设置 "Allowed" 头部。
	GlobalOPTIONS http.Handler

	// 可配置的 http.Handler,当找不到匹配的路由时调用。
	// 如果未设置,则使用 http.NotFound。
	NotFound http.Handler

	// 可配置的 http.Handler,当请求无法路由且 HandleMethodNotAllowed 为 true 时调用。
	// 如果未设置,则使用 http.Error 和 http.StatusMethodNotAllowed。
	// 在调用处理程序之前会设置包含允许请求方法的 "Allow" 头部。
	MethodNotAllowed http.Handler

	// RecoveryHandler 是处理从 http 处理程序(包括中间件和路由处理程序)恢复的 panic 的函数。
	// 如果设置,当 panic 发生并被恢复时,会调用此函数。
	// 它接收原始的 ResponseWriter、Request 和 panic 的值 (interface{})。
	// 如果未设置,则 panic 会继续传播(回到 net/http 的 ServeHTTP,可能导致连接关闭)。
	RecoveryHandler RecoveryHandlerFunc

	// FileSystemForUnmatched 用于在没有匹配到预定义路由时服务静态文件。
	// 如果设置且 ServeUnmatchedAsStatic 为 true,则未匹配路由将尝试在此文件系统中查找文件。
	FileSystemForUnmatched http.FileSystem

	// ServeUnmatchedAsStatic 如果启用,则将所有未匹配的路由尝试作为静态文件处理,
	// 使用 FileSystemForUnmatched 指定的文件系统。
	ServeUnmatchedAsStatic bool
	// contains filtered or unexported fields
}

Router 是一个 http.Handler,可用于通过可配置的路由将请求分派到不同的处理程序函数。

func New

func New() *Router

New 返回一个新的初始化 Router。 路径自动更正,包括尾部斜杠,默认启用。

func (*Router) ANY added in v0.0.3

func (r *Router) ANY(path string, handle Handle)

ANY 为所有 DefaultMethodsForAny 中定义的方法注册相同的处理函数。 这对于捕获所有类型的请求到单个端点非常有用。

func (*Router) DELETE

func (r *Router) DELETE(path string, handle Handle)

func (*Router) Delete

func (r *Router) Delete(path string, handle Handle)

func (*Router) GET

func (r *Router) GET(path string, handle Handle)

HTTP method shortcuts

func (*Router) Get

func (r *Router) Get(path string, handle Handle)

func (*Router) GetDefaultErrHandler added in v0.0.4

func (r *Router) GetDefaultErrHandler() ErrorHandlerFunc

返回默认errhandle

func (*Router) GetErrorHandler added in v0.0.4

func (r *Router) GetErrorHandler() ErrorHandlerFunc

GetErrorHandler 返回当前配置的错误处理函数。 注意:直接比较返回的函数与 defaultErrorHandler 可能不可靠。 请使用 Router.IsUsingDefaultErrorHandler() 来检查是否正在使用默认处理器。

func (*Router) Group

func (r *Router) Group(prefix string) *Group

Group 创建一个新的路由组,所有通过该组注册的路由都将带有给定的路径前缀。

func (*Router) HEAD

func (r *Router) HEAD(path string, handle Handle)

func (*Router) Handle

func (r *Router) Handle(method, path string, handle Handle)

Handle 使用给定的路径和方法注册新的请求处理程序。 ... (方法内部逻辑保持不变)

func (*Router) Handler

func (r *Router) Handler(method, path string, handler http.Handler)

Handler 是一个适配器,允许将 http.Handler 用作请求处理程序。 Params 在请求上下文中可以通过 ParamsKey 获取。 **重要**: req.Context() 会被用于传递 Params。

func (*Router) HandlerFunc

func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc)

HandlerFunc 是一个适配器,允许将 http.HandlerFunc 用作请求处理程序。

func (*Router) Head

func (r *Router) Head(path string, handle Handle)

func (*Router) IsUsingDefaultErrorHandler added in v0.0.4

func (r *Router) IsUsingDefaultErrorHandler() bool

IsUsingDefaultErrorHandler 返回 true 如果当前路由器正在使用默认的错误处理器。

func (*Router) Lookup

func (r *Router) Lookup(method, path string) (Handle, Params, bool)

Lookup 允许手动查找方法 + 路径组合。 ... (方法内部逻辑保持不变)

func (*Router) OPTIONS

func (r *Router) OPTIONS(path string, handle Handle)

func (*Router) Options

func (r *Router) Options(path string, handle Handle)

func (*Router) PATCH

func (r *Router) PATCH(path string, handle Handle)

func (*Router) POST

func (r *Router) POST(path string, handle Handle)

func (*Router) PUT

func (r *Router) PUT(path string, handle Handle)

func (*Router) Patch

func (r *Router) Patch(path string, handle Handle)

func (*Router) Post

func (r *Router) Post(path string, handle Handle)

func (*Router) Put

func (r *Router) Put(path string, handle Handle)

func (*Router) ServeFiles

func (r *Router) ServeFiles(path string, root http.FileSystem)

ServeFiles 从给定的文件系统根目录提供文件。 ... (方法内部逻辑基本保持不变, 但注意 context 的传递)

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP 使路由器实现 http.Handler 接口。 它应用全局中间件,然后执行核心路由匹配、处理和错误处理逻辑。 **重要**: req.Context() 在这里是源头,它会被传递下去。 中间件和最终的路由处理函数都可以访问和使用这个上下文。

func (*Router) ServeUnmatched

func (r *Router) ServeUnmatched(fs http.FileSystem)

ServeUnmatched 配置路由器将所有未匹配的路由尝试作为静态文件处理。 fs 指定了静态文件的根目录。

func (*Router) SetErrorHandler added in v0.0.4

func (r *Router) SetErrorHandler(handler ErrorHandlerFunc)

SetErrorHandler 允许用户设置自定义的错误处理函数。 如果传入 nil,则会恢复为默认的错误处理函数。

func (*Router) Use

func (r *Router) Use(middleware ...Middleware)

Use 将一个或多个全局中间件添加到路由器。 中间件按照添加的顺序在处理链中从外向内执行。 例如,Use(A, B) 将导致请求按 A -> B -> 最终处理程序 的顺序执行。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL