From 011e83b39019e5408ada42d7b167e4fdb046d2f2 Mon Sep 17 00:00:00 2001 From: Jason McNeil Date: Tue, 18 Jun 2024 03:27:38 -0300 Subject: [PATCH] docs: Improve ctx.Locals method description, godoc and example (#3032) * docs: Improve ctx.Locals method description, godoc and example * docs: Update ctx.md to use value receiver for fiber.Ctx in app.Use and app.Get * chore: Update userKey type in ctx.md * docs: Update ctx.md * chore: Add description for Locals method in Ctx interface --- ctx.go | 11 ++++++++++- ctx_interface_gen.go | 4 ++++ docs/api/ctx.md | 16 ++++++++-------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/ctx.go b/ctx.go index 5437d36a36..64f1e4eaf3 100644 --- a/ctx.go +++ b/ctx.go @@ -859,6 +859,10 @@ func (c *DefaultCtx) Links(link ...string) { // Locals makes it possible to pass any values under keys scoped to the request // and therefore available to all following routes that match the request. +// +// All the values are removed from ctx after returning from the top +// RequestHandler. Additionally, Close method is called on each value +// implementing io.Closer before removing the value from ctx. func (c *DefaultCtx) Locals(key any, value ...any) any { if len(value) == 0 { return c.fasthttp.UserValue(key) @@ -868,7 +872,12 @@ func (c *DefaultCtx) Locals(key any, value ...any) any { } // Locals function utilizing Go's generics feature. -// This function allows for manipulating and retrieving local values within a request context with a more specific data type. +// This function allows for manipulating and retrieving local values within a +// request context with a more specific data type. +// +// All the values are removed from ctx after returning from the top +// RequestHandler. Additionally, Close method is called on each value +// implementing io.Closer before removing the value from ctx. func Locals[V any](c Ctx, key any, value ...V) V { var v V var ok bool diff --git a/ctx_interface_gen.go b/ctx_interface_gen.go index 8107965772..5aeaf2f17a 100644 --- a/ctx_interface_gen.go +++ b/ctx_interface_gen.go @@ -174,6 +174,10 @@ type Ctx interface { Links(link ...string) // Locals makes it possible to pass any values under keys scoped to the request // and therefore available to all following routes that match the request. + // + // All the values are removed from ctx after returning from the top + // RequestHandler. Additionally, Close method is called on each value + // implementing io.Closer before removing the value from ctx. Locals(key any, value ...any) any // Location sets the response Location HTTP header to the specified path parameter. Location(path string) diff --git a/docs/api/ctx.md b/docs/api/ctx.md index bdbc4054e2..ae898181c8 100644 --- a/docs/api/ctx.md +++ b/docs/api/ctx.md @@ -945,10 +945,10 @@ app.Get("/", func(c fiber.Ctx) error { ## Locals -A method that stores variables scoped to the request and, therefore, are available only to the routes that match the request. +A method that stores variables scoped to the request and, therefore, are available only to the routes that match the request. The stored variables are removed after the request is handled. If any of the stored data implements the `io.Closer` interface, its `Close` method will be called before it's removed. :::tip -This is useful if you want to pass some **specific** data to the next middleware. +This is useful if you want to pass some **specific** data to the next middleware. Remember to perform type assertions when retrieving the data to ensure it is of the expected type. You can also use a non-exported type as a key to avoid collisions. ::: ```go title="Signature" @@ -957,26 +957,26 @@ func (c Ctx) Locals(key any, value ...any) any ```go title="Example" -// key is an unexported type for keys defined in this package. +// keyType is an unexported type for keys defined in this package. // This prevents collisions with keys defined in other packages. -type key int +type keyType int // userKey is the key for user.User values in Contexts. It is // unexported; clients use user.NewContext and user.FromContext // instead of using this key directly. -var userKey key +var userKey keyType app.Use(func(c fiber.Ctx) error { - c.Locals(userKey, "admin") + c.Locals(userKey, "admin") // Stores the string "admin" under a non-exported type key return c.Next() }) app.Get("/admin", func(c fiber.Ctx) error { - if c.Locals(userKey) == "admin" { + user, ok := c.Locals(userKey).(string) // Retrieves the data stored under the key and performs a type assertion + if ok && user == "admin" { return c.Status(fiber.StatusOK).SendString("Welcome, admin!") } return c.SendStatus(fiber.StatusForbidden) - }) ```