ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Fiber v3 如何注册并使用 RFC 10008 的 QUERY 方法(带请求体的幂等查询)

Fiber v3 如何注册并使用 RFC 10008 的 QUERY 方法(带请求体的幂等查询) Fiber v3 如何注册并使用 RFC 10008 的 QUERY 方法带请求体的幂等查询【免费下载链接】fiber⚡️ Express inspired web framework written in Go项目地址: https://gitcode.com/GitHub_Trending/fi/fiber当你需要在一次查询中携带请求体时GET不合适而误用POST又会丢失安全且幂等的语义。Fiber v3 将 HTTPQUERY方法RFC 10008作为一等动词支持它和GET一样安全、幂等但允许携带请求体用于复杂查询。本文给出在 Fiber v3 服务端注册QUERY路由、用 Fiber 自带 HTTP 客户端发送带 body 的QUERY请求并用测试代码验证路由生效的完整操作路径。前提条件Fiber v3 要求 Go1.26或更高版本升级工具链后再使用本文代码见 docs/whats_new.md。服务端导入github.com/gofiber/fiber/v3客户端导入其client包。QUERY方法常量已内置constants.go中定义MethodQuery QUERY // RFC 10008见 docs/api/constants.md 与 constants.go。注册 QUERY 路由注册入口是App上的Query方法实现在 app.go它等价于Add([]string{fiber.MethodQuery}, path, handler, handlers...)。官方给出的最小示例如下package main import ( github.com/gofiber/fiber/v3 ) func main() { app : fiber.New() // QUERY 携带请求体这是 GET 做不到的 app.Query(/search, func(c fiber.Ctx) error { // 直接把请求体作为查询条件处理这里原样回显 return c.Send(c.Body()) }) log.Fatal(app.Listen(:3000)) }同一Query注册方法还可用在以下位置签名一致按场景选一个即可见 docs/whats_new.md 的 QUERY method (RFC 10008) 一节Groupgroup.Query(/search, handler)适合挂在带前缀的分组路由下见 group.go。RouteChain 的Register接口app.RouteChain(/api).Query(handler)链式声明同一 path 上的多个动词接口定义见 register.go。Domain routerapp.Domain(api.example.com).Query(/search, handler)仅匹配指定 hostname 的请求。Query接收handler any, handlers ...any第一个 handler 之后可以追加中间件执行顺序与Add相同。在 Handler 中读取请求体QUERY与GET的关键差别就在 body。两种读取方式都已在文档中给出直接取原始字节c.Body()上例/search就是这么用的。绑定到结构体Fiber v3 的统一绑定机制支持把请求体绑定到 structc.Bind().Body(user)绑定失败时按 v3 惯例返回400type SearchQuery struct { Term string json:term TopN int json:top_n } app.Query(/search, func(c fiber.Ctx) error { var q SearchQuery if err : c.Bind().Body(q); err ! nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{error: err.Error()}) } return c.JSON(fiber.Map{matched: q.Term, limit: q.TopN}) })绑定机制统一从 URI、Body、Query、Headers、Cookies 取值的优先级等详见 docs/whats_new.md 的 Binding 一节。用测试代码验证路由生效验证方式沿用仓库自身测试app_test.go的做法通过app.Test()发送真实 HTTP 请求检查状态码与Allow头。两点判定依据均来自该测试向只注册了QUERY的路径发QUERY请求应返回200向同一路径发其他未注册方法如GET应返回405且Allow头中包含QUERY——自动响应的OPTIONS同样会在Allow头中列出QUERY。func Test_QueryRoute(t *testing.T) { app : fiber.New() app.Query(/search, func(c fiber.Ctx) error { return c.Send(c.Body()) }) // 1. QUERY 请求命中路由应为 200 resp, err : app.Test(httptest.NewRequest( fiber.MethodQuery, /search, bytes.NewBufferString({term:fiber,top_n:10}), )) if err ! nil { t.Fatal(err) } if resp.StatusCode ! fiber.StatusOK { t.Fatalf(expected 200, got %d, resp.StatusCode) } // 2. GET 未注册应为 405 且 Allow 头包含 QUERY resp, err app.Test(httptest.NewRequest(http.MethodGet, /search, nil)) if err ! nil { t.Fatal(err) } if resp.StatusCode ! fiber.StatusMethodNotAllowed { t.Fatalf(expected 405, got %d, resp.StatusCode) } if !strings.Contains(resp.Header.Get(fiber.HeaderAllow), fiber.MethodQuery) { t.Fatalf(Allow header missing QUERY: %q, resp.Header.Get(fiber.HeaderAllow)) } }注意app.Test()在未提供fiber.TestConfig时的默认值是Timeout: time.Second, FailOnTimeout: true超时行为可用TestConfig调整详见 docs/whats_new.md 的 Test Config 小节。用 Fiber Client 发送带 body 的 QUERY 请求服务端跑起来后客户端一侧同样有Query专用方法三个入口任选签名见 docs/client/rest.md 与 docs/client/request.md入口签名客户端实例func (c *Client) Query(url string, cfg ...Config) (*Response, error)单次请求对象func (r *Request) Query(url string) (*Response, error)包级默认客户端func Query(url string, cfg ...Config) (*Response, error)实例方法在 client/client.go 中实现内部把Config套到新建的Request上再派发。body 的序列化规则由Config决定默认使用 JSON若同时设置了多个 body 来源优先级为BodyFormDataFile。REST helper 创建的Request由Response.Close统一释放所以示例中defer resp.Close()不能省package main import ( fmt github.com/gofiber/fiber/v3/client ) func main() { cc : client.New() // Body 默认按 JSON 序列化后随 QUERY 请求发出 resp, err : cc.Query(http://localhost:3000/search, client.Config{ Body: map[string]any{term: fiber, top_n: 10}, }) if err ! nil { panic(err) } defer resp.Close() fmt.Println(resp.StatusCode()) fmt.Println(string(resp.Body())) }一个与QUERY直接相关的行为细节客户端的MaxRedirects只对GET、HEAD和QUERY请求生效其他方法会原样收到重定向响应见 docs/client/rest.md。中间件行为与使用限制QUERY在 v3 中被明确归类为安全且幂等fiber.IsMethodSafe和fiber.IsMethodIdempotent对QUERY都返回true因此按方法安全性做判断的中间件会把它和GET等安全方法同等对待。落到具体中间件上文档中可核对的行为如下CSRF安全方法GET、HEAD、OPTIONS、TRACE、QUERY不做 token 校验正因如此文档明确要求不要在QUERYhandler 中做状态变更docs/middleware/csrf.md。IdempotencyQUERY列在安全方法清单中幂等性中间件会将其跳过docs/middleware/idempotency.md。Early data默认只放行安全方法含QUERY的 early data可用AllowEarlyData覆盖docs/middleware/earlydata.md。CORS默认AllowMethods为GET, POST, HEAD, PUT, DELETE, PATCH, QUERYQUERY的预检会被放行docs/middleware/cors.md。Cache注意默认不缓存 QUERY缓存中间件默认只处理GET和HEAD。若要缓存QUERY响应必须把fiber.MethodQuery加进Config.Methods此时默认 key 生成器会把请求 body 并入缓存 key避免同一路径不同 body 的查询互相碰撞。若提供自定义KeyGenerator必须自行把c.Request().Body()纳入 key否则同 URL 不同 body 会串缓存docs/middleware/cache.md。也就是说QUERY的正确用法边界是把它当作带复杂条件的只读查询重复执行不应产生副作用一旦 handler 里写了写库、发消息等状态变更操作就违背了 v3 文档对安全方法的约束。小结主路径就是三步app.Query(path, handler)注册路由Group / RouteChain / Domain 同样可用→ handler 内用c.Body()或c.Bind().Body()消费请求体 → 用app.Test()断言QUERY得 200、未注册方法得 405 且Allow含QUERY客户端则通过Client.Query以 JSON body 发请求并用resp.Close()释放资源。需要缓存时记得把fiber.MethodQuery显式加入 cache 中间件的Methods否则QUERY响应默认绕过缓存。【免费下载链接】fiber⚡️ Express inspired web framework written in Go项目地址: https://gitcode.com/GitHub_Trending/fi/fiber创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表