diff --git a/versioned_docs/version-v3.x/api/_category_.json b/versioned_docs/version-v3.x/api/_category_.json deleted file mode 100644 index 1204e36b79c..00000000000 --- a/versioned_docs/version-v3.x/api/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "\uD83D\uDEE0\uFE0F API", - "position": 3, - "link": { - "type": "generated-index", - "description": "API documentation for Fiber." - } -} diff --git a/versioned_docs/version-v3.x/api/app.md b/versioned_docs/version-v3.x/api/app.md deleted file mode 100644 index 164b1edcbac..00000000000 --- a/versioned_docs/version-v3.x/api/app.md +++ /dev/null @@ -1,570 +0,0 @@ ---- -id: app -title: πŸš€ App -description: The app instance conventionally denotes the Fiber application. -sidebar_position: 2 ---- - -import Reference from '@site/src/components/reference'; - -## Routing - -import RoutingHandler from './../partials/routing/handler.md'; - -### Route Handlers - - - -### Mounting - -You can Mount Fiber instance using the [`app.Use`](./app.md#use) method similar to [`express`](https://expressjs.com/en/api.html#router.use). - -```go title="Examples" -func main() { - app := fiber.New() - micro := fiber.New() - app.Use("/john", micro) // GET /john/doe -> 200 OK - - micro.Get("/doe", func(c fiber.Ctx) error { - return c.SendStatus(fiber.StatusOK) - }) - - log.Fatal(app.Listen(":3000")) -} -``` - -### MountPath - -The `MountPath` property contains one or more path patterns on which a sub-app was mounted. - -```go title="Signature" -func (app *App) MountPath() string -``` - -```go title="Examples" -func main() { - app := fiber.New() - one := fiber.New() - two := fiber.New() - three := fiber.New() - - two.Use("/three", three) - one.Use("/two", two) - app.Use("/one", one) - - one.MountPath() // "/one" - two.MountPath() // "/one/two" - three.MountPath() // "/one/two/three" - app.MountPath() // "" -} -``` - -:::caution -Mounting order is important for MountPath. If you want to get mount paths properly, you should start mounting from the deepest app. -::: - -### Group - -You can group routes by creating a `*Group` struct. - -```go title="Signature" -func (app *App) Group(prefix string, handlers ...Handler) Router -``` - -```go title="Examples" -func main() { - app := fiber.New() - - api := app.Group("/api", handler) // /api - - v1 := api.Group("/v1", handler) // /api/v1 - v1.Get("/list", handler) // /api/v1/list - v1.Get("/user", handler) // /api/v1/user - - v2 := api.Group("/v2", handler) // /api/v2 - v2.Get("/list", handler) // /api/v2/list - v2.Get("/user", handler) // /api/v2/user - - log.Fatal(app.Listen(":3000")) -} -``` - -### Route - -Returns an instance of a single route, which you can then use to handle HTTP verbs with optional middleware. - -Similar to [`Express`](https://expressjs.com/de/api.html#app.route). - -```go title="Signature" -func (app *App) Route(path string) Register -``` - -
-Click here to see the `Register` interface - -```go -type Register interface { - All(handler Handler, middleware ...Handler) Register - Get(handler Handler, middleware ...Handler) Register - Head(handler Handler, middleware ...Handler) Register - Post(handler Handler, middleware ...Handler) Register - Put(handler Handler, middleware ...Handler) Register - Delete(handler Handler, middleware ...Handler) Register - Connect(handler Handler, middleware ...Handler) Register - Options(handler Handler, middleware ...Handler) Register - Trace(handler Handler, middleware ...Handler) Register - Patch(handler Handler, middleware ...Handler) Register - - Add(methods []string, handler Handler, middleware ...Handler) Register - - Route(path string) Register -} -``` -
- -```go title="Examples" -func main() { - app := fiber.New() - - // use `Route` as chainable route declaration method - app.Route("/test").Get(func(c fiber.Ctx) error { - return c.SendString("GET /test") - }) - - app.Route("/events").all(func(c fiber.Ctx) error { - // runs for all HTTP verbs first - // think of it as route specific middleware! - }) - .get(func(c fiber.Ctx) error { - return c.SendString("GET /events") - }) - .post(func(c fiber.Ctx) error { - // maybe add a new event... - }) - - // combine multiple routes - app.Route("/v2").Route("/user").Get(func(c fiber.Ctx) error { - return c.SendString("GET /v2/user") - }) - - // use multiple methods - app.Route("/api").Get(func(c fiber.Ctx) error { - return c.SendString("GET /api") - }).Post(func(c fiber.Ctx) error { - return c.SendString("POST /api") - }) - - log.Fatal(app.Listen(":3000")) -} -``` - -### HandlersCount - -This method returns the amount of registered handlers. - -```go title="Signature" -func (app *App) HandlersCount() uint32 -``` - -### Stack - -This method returns the original router stack - -```go title="Signature" -func (app *App) Stack() [][]*Route -``` - -```go title="Examples" -var handler = func(c fiber.Ctx) error { return nil } - -func main() { - app := fiber.New() - - app.Get("/john/:age", handler) - app.Post("/register", handler) - - data, _ := json.MarshalIndent(app.Stack(), "", " ") - fmt.Println(string(data)) - - app.Listen(":3000") -} -``` - -
-Click here to see the result - -```json -[ - [ - { - "method": "GET", - "path": "/john/:age", - "params": [ - "age" - ] - } - ], - [ - { - "method": "HEAD", - "path": "/john/:age", - "params": [ - "age" - ] - } - ], - [ - { - "method": "POST", - "path": "/register", - "params": null - } - ] -] -``` -
- -### Name - -This method assigns the name of latest created route. - -```go title="Signature" -func (app *App) Name(name string) Router -``` - -```go title="Examples" -var handler = func(c fiber.Ctx) error { return nil } - -func main() { - app := fiber.New() - - app.Get("/", handler) - app.Name("index") - - app.Get("/doe", handler).Name("home") - - app.Trace("/tracer", handler).Name("tracert") - - app.Delete("/delete", handler).Name("delete") - - a := app.Group("/a") - a.Name("fd.") - - a.Get("/test", handler).Name("test") - - data, _ := json.MarshalIndent(app.Stack(), "", " ") - fmt.Print(string(data)) - - app.Listen(":3000") - -} -``` - -
-Click here to see the result - -```json -[ - [ - { - "method": "GET", - "name": "index", - "path": "/", - "params": null - }, - { - "method": "GET", - "name": "home", - "path": "/doe", - "params": null - }, - { - "method": "GET", - "name": "fd.test", - "path": "/a/test", - "params": null - } - ], - [ - { - "method": "HEAD", - "name": "", - "path": "/", - "params": null - }, - { - "method": "HEAD", - "name": "", - "path": "/doe", - "params": null - }, - { - "method": "HEAD", - "name": "", - "path": "/a/test", - "params": null - } - ], - null, - null, - [ - { - "method": "DELETE", - "name": "delete", - "path": "/delete", - "params": null - } - ], - null, - null, - [ - { - "method": "TRACE", - "name": "tracert", - "path": "/tracer", - "params": null - } - ], - null -] -``` -
- -### GetRoute - -This method gets the route by name. - -```go title="Signature" -func (app *App) GetRoute(name string) Route -``` - -```go title="Examples" -var handler = func(c fiber.Ctx) error { return nil } - -func main() { - app := fiber.New() - - app.Get("/", handler).Name("index") - - data, _ := json.MarshalIndent(app.GetRoute("index"), "", " ") - fmt.Print(string(data)) - - - app.Listen(":3000") -} -``` - -
-Click here to see the result - -```json -{ - "method": "GET", - "name": "index", - "path": "/", - "params": null -} -``` -
- -### GetRoutes - -This method gets all routes. - -```go title="Signature" -func (app *App) GetRoutes(filterUseOption ...bool) []Route -``` - -When filterUseOption equal to true, it will filter the routes registered by the middleware. -```go title="Examples" -func main() { - app := fiber.New() - app.Post("/", func (c fiber.Ctx) error { - return c.SendString("Hello, World!") - }).Name("index") - data, _ := json.MarshalIndent(app.GetRoutes(true), "", " ") - fmt.Print(string(data)) -} -``` - -
-Click here to see the result - -```json -[ - { - "method": "POST", - "name": "index", - "path": "/", - "params": null - } -] -``` -
- -## Config - -Config returns the [app config](./fiber.md#config) as value \( read-only \). - -```go title="Signature" -func (app *App) Config() Config -``` - -## Handler - -Handler returns the server handler that can be used to serve custom [`\*fasthttp.RequestCtx`](https://pkg.go.dev/github.com/valyala/fasthttp#RequestCtx) requests. - -```go title="Signature" -func (app *App) Handler() fasthttp.RequestHandler -``` - -## ErrorHandler - -Errorhandler executes the process which was defined for the application in case of errors, this is used in some cases in middlewares. - -```go title="Signature" -func (app *App) ErrorHandler(ctx Ctx, err error) error -``` - -## NewCtxFunc - -NewCtxFunc allows to customize the ctx struct as we want. - -```go title="Signature" -func (app *App) NewCtxFunc(function func(app *App) CustomCtx) -``` - -```go title="Examples" -type CustomCtx struct { - DefaultCtx -} - -// Custom method -func (c *CustomCtx) Params(key string, defaultValue ...string) string { - return "prefix_" + c.DefaultCtx.Params(key) -} - -app := New() -app.NewCtxFunc(func(app *fiber.App) fiber.CustomCtx { - return &CustomCtx{ - DefaultCtx: *NewDefaultCtx(app), - } -}) -// curl http://localhost:3000/123 -app.Get("/:id", func(c Ctx) error { - // use custom method - output: prefix_123 - return c.SendString(c.Params("id")) -}) -``` - -## RegisterCustomBinder - -You can register custom binders to use as [`Bind().Custom("name")`](bind.md#custom). -They should be compatible with CustomBinder interface. - -```go title="Signature" -func (app *App) RegisterCustomBinder(binder CustomBinder) -``` - -```go title="Examples" -app := fiber.New() - -// My custom binder -customBinder := &customBinder{} -// Name of custom binder, which will be used as Bind().Custom("name") -func (*customBinder) Name() string { - return "custom" -} -// Is used in the Body Bind method to check if the binder should be used for custom mime types -func (*customBinder) MIMETypes() []string { - return []string{"application/yaml"} -} -// Parse the body and bind it to the out interface -func (*customBinder) Parse(c Ctx, out any) error { - // parse yaml body - return yaml.Unmarshal(c.Body(), out) -} -// Register custom binder -app.RegisterCustomBinder(customBinder) - -// curl -X POST http://localhost:3000/custom -H "Content-Type: application/yaml" -d "name: John" -app.Post("/custom", func(c Ctx) error { - var user User - // output: {Name:John} - // Custom binder is used by the name - if err := c.Bind().Custom("custom", &user); err != nil { - return err - } - // ... - return c.JSON(user) -}) -// curl -X POST http://localhost:3000/normal -H "Content-Type: application/yaml" -d "name: Doe" -app.Post("/normal", func(c Ctx) error { - var user User - // output: {Name:Doe} - // Custom binder is used by the mime type - if err := c.Bind().Body(&user); err != nil { - return err - } - // ... - return c.JSON(user) -}) -``` - -## RegisterCustomConstraint - -RegisterCustomConstraint allows to register custom constraint. - -```go title="Signature" -func (app *App) RegisterCustomConstraint(constraint CustomConstraint) -``` - -See [Custom Constraint](../guide/routing.md#custom-constraint) section for more information. - - -## SetTLSHandler - -Use SetTLSHandler to set [ClientHelloInfo](https://datatracker.ietf.org/doc/html/rfc8446#section-4.1.2) when using TLS with Listener. - -```go title="Signature" -func (app *App) SetTLSHandler(tlsHandler *TLSHandler) -``` - -## Test - -Testing your application is done with the **Test** method. Use this method for creating `_test.go` files or when you need to debug your routing logic. The default timeout is `1s` if you want to disable a timeout altogether, pass `-1` as a second argument. - -```go title="Signature" -func (app *App) Test(req *http.Request, msTimeout ...int) (*http.Response, error) -``` - -```go title="Examples" -// Create route with GET method for test: -app.Get("/", func(c fiber.Ctx) error { - fmt.Println(c.BaseURL()) // => http://google.com - fmt.Println(c.Get("X-Custom-Header")) // => hi - - return c.SendString("hello, World!") -}) - -// http.Request -req := httptest.NewRequest("GET", "http://google.com", nil) -req.Header.Set("X-Custom-Header", "hi") - -// http.Response -resp, _ := app.Test(req) - -// Do something with results: -if resp.StatusCode == fiber.StatusOK { - body, _ := io.ReadAll(resp.Body) - fmt.Println(string(body)) // => Hello, World! -} -``` - -## Hooks - -Hooks is a method to return [hooks](./hooks.md) property. - -```go title="Signature" -func (app *App) Hooks() *Hooks -``` diff --git a/versioned_docs/version-v3.x/api/bind.md b/versioned_docs/version-v3.x/api/bind.md deleted file mode 100644 index f955202e287..00000000000 --- a/versioned_docs/version-v3.x/api/bind.md +++ /dev/null @@ -1,590 +0,0 @@ ---- -id: bind -title: πŸ“Ž Bind -description: Binds the request and response items to a struct. -sidebar_position: 4 -toc_max_heading_level: 4 ---- - -Bindings are used to parse the request/response body, query parameters, cookies and much more into a struct. - -:::info - -All binder returned value are only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - - -## Binders - -- [Body](#body) - - [Form](#form) - - [JSON](#json) - - [MultipartForm](#multipartform) - - [XML](#xml) -- [Cookie](#cookie) -- [Header](#header) -- [Query](#query) -- [RespHeader](#respheader) -- [URI](#uri) - -### Body - -Binds the request body to a struct. - -It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a JSON body with a field called Pass, you would use a struct field of `json:"pass"`. - -| content-type | struct tag | -| ----------------------------------- | ---------- | -| `application/x-www-form-urlencoded` | form | -| `multipart/form-data` | form | -| `application/json` | json | -| `application/xml` | xml | -| `text/xml` | xml | - -```go title="Signature" -func (b *Bind) Body(out any) error -``` - -```go title="Example" -// Field names should start with an uppercase letter -type Person struct { - Name string `json:"name" xml:"name" form:"name"` - Pass string `json:"pass" xml:"pass" form:"pass"` -} - -app.Post("/", func(c fiber.Ctx) error { - p := new(Person) - - if err := c.Bind().Body(p); err != nil { - return err - } - - log.Println(p.Name) // john - log.Println(p.Pass) // doe - - // ... -}) - -// Run tests with the following curl commands - -// curl -X POST -H "Content-Type: application/json" --data "{\"name\":\"john\",\"pass\":\"doe\"}" localhost:3000 - -// curl -X POST -H "Content-Type: application/xml" --data "johndoe" localhost:3000 - -// curl -X POST -H "Content-Type: application/x-www-form-urlencoded" --data "name=john&pass=doe" localhost:3000 - -// curl -X POST -F name=john -F pass=doe http://localhost:3000 - -// curl -X POST "http://localhost:3000/?name=john&pass=doe" -``` - - -**The methods for the various bodies can also be used directly:** - -#### Form - -Binds the request form body to a struct. - -It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a Form body with a field called Pass, you would use a struct field of `form:"pass"`. - - -```go title="Signature" -func (b *Bind) Form(out any) error -``` - -```go title="Example" -// Field names should start with an uppercase letter -type Person struct { - Name string `form:"name"` - Pass string `form:"pass"` -} - -app.Post("/", func(c fiber.Ctx) error { - p := new(Person) - - if err := c.Bind().Form(p); err != nil { - return err - } - - log.Println(p.Name) // john - log.Println(p.Pass) // doe - - // ... -}) - -// Run tests with the following curl commands - -// curl -X POST -H "Content-Type: application/x-www-form-urlencoded" --data "name=john&pass=doe" localhost:3000 -``` - -#### JSON - -Binds the request json body to a struct. - -It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a JSON body with a field called Pass, you would use a struct field of `json:"pass"`. - - -```go title="Signature" -func (b *Bind) JSON(out any) error -``` - -```go title="Example" -// Field names should start with an uppercase letter -type Person struct { - Name string `json:"name"` - Pass string `json:"pass"` -} - -app.Post("/", func(c fiber.Ctx) error { - p := new(Person) - - if err := c.Bind().JSON(p); err != nil { - return err - } - - log.Println(p.Name) // john - log.Println(p.Pass) // doe - - // ... -}) - -// Run tests with the following curl commands - -// curl -X POST -H "Content-Type: application/json" --data "{\"name\":\"john\",\"pass\":\"doe\"}" localhost:3000 - -``` - -#### MultipartForm - -Binds the request multipart form body to a struct. - -It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a MultipartForm body with a field called Pass, you would use a struct field of `form:"pass"`. - - -```go title="Signature" -func (b *Bind) MultipartForm(out any) error -``` - -```go title="Example" -// Field names should start with an uppercase letter -type Person struct { - Name string `form:"name"` - Pass string `form:"pass"` -} - -app.Post("/", func(c fiber.Ctx) error { - p := new(Person) - - if err := c.Bind().MultipartForm(p); err != nil { - return err - } - - log.Println(p.Name) // john - log.Println(p.Pass) // doe - - // ... -}) - -// Run tests with the following curl commands - -// curl -X POST -H "Content-Type: multipart/form-data" -F "name=john" -F "pass=doe" localhost:3000 - -``` - -#### XML - -Binds the request xml form body to a struct. - -It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a XML body with a field called Pass, you would use a struct field of `xml:"pass"`. - - -```go title="Signature" -func (b *Bind) XML(out any) error -``` - -```go title="Example" -// Field names should start with an uppercase letter -type Person struct { - Name string `xml:"name"` - Pass string `xml:"pass"` -} - -app.Post("/", func(c fiber.Ctx) error { - p := new(Person) - - if err := c.Bind().XML(p); err != nil { - return err - } - - log.Println(p.Name) // john - log.Println(p.Pass) // doe - - // ... -}) - -// Run tests with the following curl commands - -// curl -X POST -H "Content-Type: application/xml" --data "johndoe" localhost:3000 -``` - - -### Cookie - -This method is similar to [Body-Binding](#body), but for cookie parameters. -It is important to use the struct tag "cookie". For example, if you want to parse a cookie with a field called Age, you would use a struct field of `cookie:"age"`. - -```go title="Signature" -func (b *Bind) Cookie(out any) error -``` - -```go title="Example" -// Field names should start with an uppercase letter -type Person struct { - Name string `cookie:"name"` - Age int `cookie:"age"` - Job bool `cookie:"job"` -} - -app.Get("/", func(c fiber.Ctx) error { - p := new(Person) - - if err := c.Bind().Cookie(p); err != nil { - return err - } - - log.Println(p.Name) // Joseph - log.Println(p.Age) // 23 - log.Println(p.Job) // true -}) -// Run tests with the following curl command -// curl.exe --cookie "name=Joseph; age=23; job=true" http://localhost:8000/ -``` - - -### Header - -This method is similar to [Body-Binding](#body), but for request headers. -It is important to use the struct tag "header". For example, if you want to parse a request header with a field called Pass, you would use a struct field of `header:"pass"`. - -```go title="Signature" -func (b *Bind) Header(out any) error -``` - -```go title="Example" -// Field names should start with an uppercase letter -type Person struct { - Name string `header:"name"` - Pass string `header:"pass"` - Products []string `header:"products"` -} - -app.Get("/", func(c fiber.Ctx) error { - p := new(Person) - - if err := c.Bind().Header(p); err != nil { - return err - } - - log.Println(p.Name) // john - log.Println(p.Pass) // doe - log.Println(p.Products) // [shoe, hat] - - // ... -}) -// Run tests with the following curl command - -// curl "http://localhost:3000/" -H "name: john" -H "pass: doe" -H "products: shoe,hat" -``` - - -### Query - -This method is similar to [Body-Binding](#body), but for query parameters. -It is important to use the struct tag "query". For example, if you want to parse a query parameter with a field called Pass, you would use a struct field of `query:"pass"`. - -```go title="Signature" -func (b *Bind) Query(out any) error -``` - -```go title="Example" -// Field names should start with an uppercase letter -type Person struct { - Name string `query:"name"` - Pass string `query:"pass"` - Products []string `query:"products"` -} - -app.Get("/", func(c fiber.Ctx) error { - p := new(Person) - - if err := c.Bind().Query(p); err != nil { - return err - } - - log.Println(p.Name) // john - log.Println(p.Pass) // doe - // fiber.Config{EnableSplittingOnParsers: false} - default - log.Println(p.Products) // ["shoe,hat"] - // fiber.Config{EnableSplittingOnParsers: true} - // log.Println(p.Products) // ["shoe", "hat"] - - - // ... -}) -// Run tests with the following curl command - -// curl "http://localhost:3000/?name=john&pass=doe&products=shoe,hat" -``` - -:::info -For more parser settings please look here [Config](fiber.md#enablesplittingonparsers) -::: - - -### RespHeader - -This method is similar to [Body-Binding](#body), but for response headers. -It is important to use the struct tag "respHeader". For example, if you want to parse a request header with a field called Pass, you would use a struct field of `respHeader:"pass"`. - -```go title="Signature" -func (b *Bind) Header(out any) error -``` - -```go title="Example" -// Field names should start with an uppercase letter -type Person struct { - Name string `respHeader:"name"` - Pass string `respHeader:"pass"` - Products []string `respHeader:"products"` -} - -app.Get("/", func(c fiber.Ctx) error { - p := new(Person) - - if err := c.Bind().RespHeader(p); err != nil { - return err - } - - log.Println(p.Name) // john - log.Println(p.Pass) // doe - log.Println(p.Products) // [shoe, hat] - - // ... -}) -// Run tests with the following curl command - -// curl "http://localhost:3000/" -H "name: john" -H "pass: doe" -H "products: shoe,hat" -``` - -### URI - -This method is similar to [Body-Binding](#body), but for path parameters. It is important to use the struct tag "uri". For example, if you want to parse a path parameter with a field called Pass, you would use a struct field of uri:"pass" - -```go title="Signature" -func (b *Bind) URI(out any) error -``` - -```go title="Example" -// GET http://example.com/user/111 -app.Get("/user/:id", func(c fiber.Ctx) error { - param := struct {ID uint `uri:"id"`}{} - - c.Bind().URI(¶m) // "{"id": 111}" - - // ... -}) - -``` - -## Custom - -To use custom binders, you have to use this method. - -You can register them from [RegisterCustomBinder](./app.md#registercustombinder) method of Fiber instance. - -```go title="Signature" -func (b *Bind) Custom(name string, dest any) error -``` - -```go title="Example" -app := fiber.New() - -// My custom binder -customBinder := &customBinder{} -// Name of custom binder, which will be used as Bind().Custom("name") -func (*customBinder) Name() string { - return "custom" -} -// Is used in the Body Bind method to check if the binder should be used for custom mime types -func (*customBinder) MIMETypes() []string { - return []string{"application/yaml"} -} -// Parse the body and bind it to the out interface -func (*customBinder) Parse(c Ctx, out any) error { - // parse yaml body - return yaml.Unmarshal(c.Body(), out) -} -// Register custom binder -app.RegisterCustomBinder(customBinder) - -// curl -X POST http://localhost:3000/custom -H "Content-Type: application/yaml" -d "name: John" -app.Post("/custom", func(c Ctx) error { - var user User - // output: {Name:John} - // Custom binder is used by the name - if err := c.Bind().Custom("custom", &user); err != nil { - return err - } - // ... - return c.JSON(user) -}) -``` - -Internally they are also used in the [Body](#body) method. -For this the MIMETypes method is used to check if the custom binder should be used for the given content type. - -## Options - -For more control over the error handling, you can use the following methods. - -### Must - -If you want to handle binder errors automatically, you can use Must. -If there's an error it'll return error and 400 as HTTP status. - -```go title="Signature" -func (b *Bind) Must() *Bind -``` - -### Should - -To handle binder errors manually, you can prefer Should method. -It's default behavior of binder. - -```go title="Signature" -func (b *Bind) Should() *Bind -``` - - -## SetParserDecoder - -Allow you to config BodyParser/QueryParser decoder, base on schema's options, providing possibility to add custom type for parsing. - -```go title="Signature" -func SetParserDecoder(parserConfig fiber.ParserConfig{ - IgnoreUnknownKeys bool, - ParserType []fiber.ParserType{ - Customtype any, - Converter func(string) reflect.Value, - }, - ZeroEmpty bool, - SetAliasTag string, -}) -``` - -```go title="Example" - -type CustomTime time.Time - -// String() returns the time in string -func (ct *CustomTime) String() string { - t := time.Time(*ct).String() - return t - } - - // Register the converter for CustomTime type format as 2006-01-02 - var timeConverter = func(value string) reflect.Value { - fmt.Println("timeConverter", value) - if v, err := time.Parse("2006-01-02", value); err == nil { - return reflect.ValueOf(v) - } - return reflect.Value{} -} - -customTime := fiber.ParserType{ - Customtype: CustomTime{}, - Converter: timeConverter, -} - -// Add setting to the Decoder -fiber.SetParserDecoder(fiber.ParserConfig{ - IgnoreUnknownKeys: true, - ParserType: []fiber.ParserType{customTime}, - ZeroEmpty: true, -}) - -// Example to use CustomType, you pause custom time format not in RFC3339 -type Demo struct { - Date CustomTime `form:"date" query:"date"` - Title string `form:"title" query:"title"` - Body string `form:"body" query:"body"` -} - -app.Post("/body", func(c fiber.Ctx) error { - var d Demo - c.BodyParser(&d) - fmt.Println("d.Date", d.Date.String()) - return c.JSON(d) -}) - -app.Get("/query", func(c fiber.Ctx) error { - var d Demo - c.QueryParser(&d) - fmt.Println("d.Date", d.Date.String()) - return c.JSON(d) -}) - -// curl -X POST -F title=title -F body=body -F date=2021-10-20 http://localhost:3000/body - -// curl -X GET "http://localhost:3000/query?title=title&body=body&date=2021-10-20" - -``` - - -## Validation - -Validation is also possible with the binding methods. You can specify your validation rules using the `validate` struct tag. - -Specify your struct validator in the [config](./fiber.md#structvalidator) - -Setup your validator in the config: - -```go title="Example" -import "github.com/go-playground/validator/v10" - -type structValidator struct { - validate *validator.Validate -} - -// Validator needs to implement the Validate method -func (v *structValidator) Validate(out any) error { - return v.validate.Struct(out) -} - -// Setup your validator in the config -app := fiber.New(fiber.Config{ - StructValidator: &structValidator{validate: validator.New()}, -}) -``` - -Usage of the validation in the binding methods: - -```go title="Example" -type Person struct { - Name string `json:"name" validate:"required"` - Age int `json:"age" validate:"gte=18,lte=60"` -} - -app.Post("/", func(c fiber.Ctx) error { - p := new(Person) - - if err := c.Bind().JSON(p); err != nil {// <- here you receive the validation errors - return err - } -}) -``` - - - diff --git a/versioned_docs/version-v3.x/api/constants.md b/versioned_docs/version-v3.x/api/constants.md deleted file mode 100644 index a9ee6d5a05e..00000000000 --- a/versioned_docs/version-v3.x/api/constants.md +++ /dev/null @@ -1,294 +0,0 @@ ---- -id: constants -title: πŸ“‹ Constants -description: Some constants for Fiber. -sidebar_position: 8 ---- - -### HTTP methods were copied from net/http. - -```go -const ( - MethodGet = "GET" // RFC 7231, 4.3.1 - MethodHead = "HEAD" // RFC 7231, 4.3.2 - MethodPost = "POST" // RFC 7231, 4.3.3 - MethodPut = "PUT" // RFC 7231, 4.3.4 - MethodPatch = "PATCH" // RFC 5789 - MethodDelete = "DELETE" // RFC 7231, 4.3.5 - MethodConnect = "CONNECT" // RFC 7231, 4.3.6 - MethodOptions = "OPTIONS" // RFC 7231, 4.3.7 - MethodTrace = "TRACE" // RFC 7231, 4.3.8 - methodUse = "USE" -) -``` - -### MIME types that are commonly used - -```go -const ( - MIMETextXML = "text/xml" - MIMETextHTML = "text/html" - MIMETextPlain = "text/plain" - MIMETextJavaScript = "text/javascript" - MIMETextCSS = "text/css" - MIMEApplicationXML = "application/xml" - MIMEApplicationJSON = "application/json" - MIMEApplicationJavaScript = "application/javascript" - MIMEApplicationForm = "application/x-www-form-urlencoded" - MIMEOctetStream = "application/octet-stream" - MIMEMultipartForm = "multipart/form-data" - - MIMETextXMLCharsetUTF8 = "text/xml; charset=utf-8" - MIMETextHTMLCharsetUTF8 = "text/html; charset=utf-8" - MIMETextPlainCharsetUTF8 = "text/plain; charset=utf-8" - MIMETextJavaScriptCharsetUTF8 = "text/javascript; charset=utf-8" - MIMETextCSSCharsetUTF8 = "text/css; charset=utf-8" - MIMEApplicationXMLCharsetUTF8 = "application/xml; charset=utf-8" - MIMEApplicationJSONCharsetUTF8 = "application/json; charset=utf-8" - MIMEApplicationJavaScriptCharsetUTF8 = "application/javascript; charset=utf-8" -)``` - -### HTTP status codes were copied from net/http. - -```go -const ( - StatusContinue = 100 // RFC 7231, 6.2.1 - StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2 - StatusProcessing = 102 // RFC 2518, 10.1 - StatusEarlyHints = 103 // RFC 8297 - StatusOK = 200 // RFC 7231, 6.3.1 - StatusCreated = 201 // RFC 7231, 6.3.2 - StatusAccepted = 202 // RFC 7231, 6.3.3 - StatusNonAuthoritativeInformation = 203 // RFC 7231, 6.3.4 - StatusNoContent = 204 // RFC 7231, 6.3.5 - StatusResetContent = 205 // RFC 7231, 6.3.6 - StatusPartialContent = 206 // RFC 7233, 4.1 - StatusMultiStatus = 207 // RFC 4918, 11.1 - StatusAlreadyReported = 208 // RFC 5842, 7.1 - StatusIMUsed = 226 // RFC 3229, 10.4.1 - StatusMultipleChoices = 300 // RFC 7231, 6.4.1 - StatusMovedPermanently = 301 // RFC 7231, 6.4.2 - StatusFound = 302 // RFC 7231, 6.4.3 - StatusSeeOther = 303 // RFC 7231, 6.4.4 - StatusNotModified = 304 // RFC 7232, 4.1 - StatusUseProxy = 305 // RFC 7231, 6.4.5 - StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7 - StatusPermanentRedirect = 308 // RFC 7538, 3 - StatusBadRequest = 400 // RFC 7231, 6.5.1 - StatusUnauthorized = 401 // RFC 7235, 3.1 - StatusPaymentRequired = 402 // RFC 7231, 6.5.2 - StatusForbidden = 403 // RFC 7231, 6.5.3 - StatusNotFound = 404 // RFC 7231, 6.5.4 - StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5 - StatusNotAcceptable = 406 // RFC 7231, 6.5.6 - StatusProxyAuthRequired = 407 // RFC 7235, 3.2 - StatusRequestTimeout = 408 // RFC 7231, 6.5.7 - StatusConflict = 409 // RFC 7231, 6.5.8 - StatusGone = 410 // RFC 7231, 6.5.9 - StatusLengthRequired = 411 // RFC 7231, 6.5.10 - StatusPreconditionFailed = 412 // RFC 7232, 4.2 - StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11 - StatusRequestURITooLong = 414 // RFC 7231, 6.5.12 - StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13 - StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4 - StatusExpectationFailed = 417 // RFC 7231, 6.5.14 - StatusTeapot = 418 // RFC 7168, 2.3.3 - StatusMisdirectedRequest = 421 // RFC 7540, 9.1.2 - StatusUnprocessableEntity = 422 // RFC 4918, 11.2 - StatusLocked = 423 // RFC 4918, 11.3 - StatusFailedDependency = 424 // RFC 4918, 11.4 - StatusTooEarly = 425 // RFC 8470, 5.2. - StatusUpgradeRequired = 426 // RFC 7231, 6.5.15 - StatusPreconditionRequired = 428 // RFC 6585, 3 - StatusTooManyRequests = 429 // RFC 6585, 4 - StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5 - StatusUnavailableForLegalReasons = 451 // RFC 7725, 3 - StatusInternalServerError = 500 // RFC 7231, 6.6.1 - StatusNotImplemented = 501 // RFC 7231, 6.6.2 - StatusBadGateway = 502 // RFC 7231, 6.6.3 - StatusServiceUnavailable = 503 // RFC 7231, 6.6.4 - StatusGatewayTimeout = 504 // RFC 7231, 6.6.5 - StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6 - StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1 - StatusInsufficientStorage = 507 // RFC 4918, 11.5 - StatusLoopDetected = 508 // RFC 5842, 7.2 - StatusNotExtended = 510 // RFC 2774, 7 - StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6 -) -``` - -### Errors - -```go -var ( - ErrBadRequest = NewError(StatusBadRequest) // RFC 7231, 6.5.1 - ErrUnauthorized = NewError(StatusUnauthorized) // RFC 7235, 3.1 - ErrPaymentRequired = NewError(StatusPaymentRequired) // RFC 7231, 6.5.2 - ErrForbidden = NewError(StatusForbidden) // RFC 7231, 6.5.3 - ErrNotFound = NewError(StatusNotFound) // RFC 7231, 6.5.4 - ErrMethodNotAllowed = NewError(StatusMethodNotAllowed) // RFC 7231, 6.5.5 - ErrNotAcceptable = NewError(StatusNotAcceptable) // RFC 7231, 6.5.6 - ErrProxyAuthRequired = NewError(StatusProxyAuthRequired) // RFC 7235, 3.2 - ErrRequestTimeout = NewError(StatusRequestTimeout) // RFC 7231, 6.5.7 - ErrConflict = NewError(StatusConflict) // RFC 7231, 6.5.8 - ErrGone = NewError(StatusGone) // RFC 7231, 6.5.9 - ErrLengthRequired = NewError(StatusLengthRequired) // RFC 7231, 6.5.10 - ErrPreconditionFailed = NewError(StatusPreconditionFailed) // RFC 7232, 4.2 - ErrRequestEntityTooLarge = NewError(StatusRequestEntityTooLarge) // RFC 7231, 6.5.11 - ErrRequestURITooLong = NewError(StatusRequestURITooLong) // RFC 7231, 6.5.12 - ErrUnsupportedMediaType = NewError(StatusUnsupportedMediaType) // RFC 7231, 6.5.13 - ErrRequestedRangeNotSatisfiable = NewError(StatusRequestedRangeNotSatisfiable) // RFC 7233, 4.4 - ErrExpectationFailed = NewError(StatusExpectationFailed) // RFC 7231, 6.5.14 - ErrTeapot = NewError(StatusTeapot) // RFC 7168, 2.3.3 - ErrMisdirectedRequest = NewError(StatusMisdirectedRequest) // RFC 7540, 9.1.2 - ErrUnprocessableEntity = NewError(StatusUnprocessableEntity) // RFC 4918, 11.2 - ErrLocked = NewError(StatusLocked) // RFC 4918, 11.3 - ErrFailedDependency = NewError(StatusFailedDependency) // RFC 4918, 11.4 - ErrTooEarly = NewError(StatusTooEarly) // RFC 8470, 5.2. - ErrUpgradeRequired = NewError(StatusUpgradeRequired) // RFC 7231, 6.5.15 - ErrPreconditionRequired = NewError(StatusPreconditionRequired) // RFC 6585, 3 - ErrTooManyRequests = NewError(StatusTooManyRequests) // RFC 6585, 4 - ErrRequestHeaderFieldsTooLarge = NewError(StatusRequestHeaderFieldsTooLarge) // RFC 6585, 5 - ErrUnavailableForLegalReasons = NewError(StatusUnavailableForLegalReasons) // RFC 7725, 3 - ErrInternalServerError = NewError(StatusInternalServerError) // RFC 7231, 6.6.1 - ErrNotImplemented = NewError(StatusNotImplemented) // RFC 7231, 6.6.2 - ErrBadGateway = NewError(StatusBadGateway) // RFC 7231, 6.6.3 - ErrServiceUnavailable = NewError(StatusServiceUnavailable) // RFC 7231, 6.6.4 - ErrGatewayTimeout = NewError(StatusGatewayTimeout) // RFC 7231, 6.6.5 - ErrHTTPVersionNotSupported = NewError(StatusHTTPVersionNotSupported) // RFC 7231, 6.6.6 - ErrVariantAlsoNegotiates = NewError(StatusVariantAlsoNegotiates) // RFC 2295, 8.1 - ErrInsufficientStorage = NewError(StatusInsufficientStorage) // RFC 4918, 11.5 - ErrLoopDetected = NewError(StatusLoopDetected) // RFC 5842, 7.2 - ErrNotExtended = NewError(StatusNotExtended) // RFC 2774, 7 - ErrNetworkAuthenticationRequired = NewError(StatusNetworkAuthenticationRequired) // RFC 6585, 6 -) -``` - -HTTP Headers were copied from net/http. - -```go -const ( - HeaderAuthorization = "Authorization" - HeaderProxyAuthenticate = "Proxy-Authenticate" - HeaderProxyAuthorization = "Proxy-Authorization" - HeaderWWWAuthenticate = "WWW-Authenticate" - HeaderAge = "Age" - HeaderCacheControl = "Cache-Control" - HeaderClearSiteData = "Clear-Site-Data" - HeaderExpires = "Expires" - HeaderPragma = "Pragma" - HeaderWarning = "Warning" - HeaderAcceptCH = "Accept-CH" - HeaderAcceptCHLifetime = "Accept-CH-Lifetime" - HeaderContentDPR = "Content-DPR" - HeaderDPR = "DPR" - HeaderEarlyData = "Early-Data" - HeaderSaveData = "Save-Data" - HeaderViewportWidth = "Viewport-Width" - HeaderWidth = "Width" - HeaderETag = "ETag" - HeaderIfMatch = "If-Match" - HeaderIfModifiedSince = "If-Modified-Since" - HeaderIfNoneMatch = "If-None-Match" - HeaderIfUnmodifiedSince = "If-Unmodified-Since" - HeaderLastModified = "Last-Modified" - HeaderVary = "Vary" - HeaderConnection = "Connection" - HeaderKeepAlive = "Keep-Alive" - HeaderAccept = "Accept" - HeaderAcceptCharset = "Accept-Charset" - HeaderAcceptEncoding = "Accept-Encoding" - HeaderAcceptLanguage = "Accept-Language" - HeaderCookie = "Cookie" - HeaderExpect = "Expect" - HeaderMaxForwards = "Max-Forwards" - HeaderSetCookie = "Set-Cookie" - HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials" - HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers" - HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods" - HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin" - HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers" - HeaderAccessControlMaxAge = "Access-Control-Max-Age" - HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers" - HeaderAccessControlRequestMethod = "Access-Control-Request-Method" - HeaderOrigin = "Origin" - HeaderTimingAllowOrigin = "Timing-Allow-Origin" - HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies" - HeaderDNT = "DNT" - HeaderTk = "Tk" - HeaderContentDisposition = "Content-Disposition" - HeaderContentEncoding = "Content-Encoding" - HeaderContentLanguage = "Content-Language" - HeaderContentLength = "Content-Length" - HeaderContentLocation = "Content-Location" - HeaderContentType = "Content-Type" - HeaderForwarded = "Forwarded" - HeaderVia = "Via" - HeaderXForwardedFor = "X-Forwarded-For" - HeaderXForwardedHost = "X-Forwarded-Host" - HeaderXForwardedProto = "X-Forwarded-Proto" - HeaderXForwardedProtocol = "X-Forwarded-Protocol" - HeaderXForwardedSsl = "X-Forwarded-Ssl" - HeaderXUrlScheme = "X-Url-Scheme" - HeaderLocation = "Location" - HeaderFrom = "From" - HeaderHost = "Host" - HeaderReferer = "Referer" - HeaderReferrerPolicy = "Referrer-Policy" - HeaderUserAgent = "User-Agent" - HeaderAllow = "Allow" - HeaderServer = "Server" - HeaderAcceptRanges = "Accept-Ranges" - HeaderContentRange = "Content-Range" - HeaderIfRange = "If-Range" - HeaderRange = "Range" - HeaderContentSecurityPolicy = "Content-Security-Policy" - HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only" - HeaderCrossOriginResourcePolicy = "Cross-Origin-Resource-Policy" - HeaderExpectCT = "Expect-CT" - HeaderFeaturePolicy = "Feature-Policy" - HeaderPublicKeyPins = "Public-Key-Pins" - HeaderPublicKeyPinsReportOnly = "Public-Key-Pins-Report-Only" - HeaderStrictTransportSecurity = "Strict-Transport-Security" - HeaderUpgradeInsecureRequests = "Upgrade-Insecure-Requests" - HeaderXContentTypeOptions = "X-Content-Type-Options" - HeaderXDownloadOptions = "X-Download-Options" - HeaderXFrameOptions = "X-Frame-Options" - HeaderXPoweredBy = "X-Powered-By" - HeaderXXSSProtection = "X-XSS-Protection" - HeaderLastEventID = "Last-Event-ID" - HeaderNEL = "NEL" - HeaderPingFrom = "Ping-From" - HeaderPingTo = "Ping-To" - HeaderReportTo = "Report-To" - HeaderTE = "TE" - HeaderTrailer = "Trailer" - HeaderTransferEncoding = "Transfer-Encoding" - HeaderSecWebSocketAccept = "Sec-WebSocket-Accept" - HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions" - HeaderSecWebSocketKey = "Sec-WebSocket-Key" - HeaderSecWebSocketProtocol = "Sec-WebSocket-Protocol" - HeaderSecWebSocketVersion = "Sec-WebSocket-Version" - HeaderAcceptPatch = "Accept-Patch" - HeaderAcceptPushPolicy = "Accept-Push-Policy" - HeaderAcceptSignature = "Accept-Signature" - HeaderAltSvc = "Alt-Svc" - HeaderDate = "Date" - HeaderIndex = "Index" - HeaderLargeAllocation = "Large-Allocation" - HeaderLink = "Link" - HeaderPushPolicy = "Push-Policy" - HeaderRetryAfter = "Retry-After" - HeaderServerTiming = "Server-Timing" - HeaderSignature = "Signature" - HeaderSignedHeaders = "Signed-Headers" - HeaderSourceMap = "SourceMap" - HeaderUpgrade = "Upgrade" - HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control" - HeaderXPingback = "X-Pingback" - HeaderXRequestID = "X-Request-ID" - HeaderXRequestedWith = "X-Requested-With" - HeaderXRobotsTag = "X-Robots-Tag" - HeaderXUACompatible = "X-UA-Compatible" -) -``` diff --git a/versioned_docs/version-v3.x/api/ctx.md b/versioned_docs/version-v3.x/api/ctx.md deleted file mode 100644 index 0434671cd68..00000000000 --- a/versioned_docs/version-v3.x/api/ctx.md +++ /dev/null @@ -1,2172 +0,0 @@ ---- -id: ctx -title: 🧠 Ctx -description: >- - The Ctx interface represents the Context which hold the HTTP request and - response. It has methods for the request query string, parameters, body, HTTP - headers, and so on. -sidebar_position: 3 ---- - -## Accepts - -Checks, if the specified **extensions** or **content** **types** are acceptable. - -:::info -Based on the request’s [Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) HTTP header. -::: - -```go title="Signature" -func (c Ctx) Accepts(offers ...string) string -func (c Ctx) AcceptsCharsets(offers ...string) string -func (c Ctx) AcceptsEncodings(offers ...string) string -func (c Ctx) AcceptsLanguages(offers ...string) string -``` - -```go title="Example" -// Accept: text/html, application/json; q=0.8, text/plain; q=0.5; charset="utf-8" - -app.Get("/", func(c fiber.Ctx) error { - c.Accepts("html") // "html" - c.Accepts("text/html") // "text/html" - c.Accepts("json", "text") // "json" - c.Accepts("application/json") // "application/json" - c.Accepts("text/plain", "application/json") // "application/json", due to quality - c.Accepts("image/png") // "" - c.Accepts("png") // "" - // ... -}) -``` - -```go title="Example 2" -// Accept: text/html, text/*, application/json, */*; q=0 - -app.Get("/", func(c fiber.Ctx) error { - c.Accepts("text/plain", "application/json") // "application/json", due to specificity - c.Accepts("application/json", "text/html") // "text/html", due to first match - c.Accepts("image/png") // "", due to */* without q factor 0 is Not Acceptable - // ... -}) -``` - -Media-Type parameters are supported. - -```go title="Example 3" -// Accept: text/plain, application/json; version=1; foo=bar - -app.Get("/", func(c fiber.Ctx) error { - // Extra parameters in the accept are ignored - c.Accepts("text/plain;format=flowed") // "text/plain;format=flowed" - - // An offer must contain all parameters present in the Accept type - c.Accepts("application/json") // "" - - // Parameter order and capitalization does not matter. Quotes on values are stripped. - c.Accepts(`application/json;foo="bar";VERSION=1`) // "application/json;foo="bar";VERSION=1" -}) -``` - -```go title="Example 4" -// Accept: text/plain;format=flowed;q=0.9, text/plain -// i.e., "I prefer text/plain;format=flowed less than other forms of text/plain" -app.Get("/", func(c fiber.Ctx) error { - // Beware: the order in which offers are listed matters. - // Although the client specified they prefer not to receive format=flowed, - // the text/plain Accept matches with "text/plain;format=flowed" first, so it is returned. - c.Accepts("text/plain;format=flowed", "text/plain") // "text/plain;format=flowed" - - // Here, things behave as expected: - c.Accepts("text/plain", "text/plain;format=flowed") // "text/plain" -}) -``` - -Fiber provides similar functions for the other accept headers. - -```go -// Accept-Charset: utf-8, iso-8859-1;q=0.2 -// Accept-Encoding: gzip, compress;q=0.2 -// Accept-Language: en;q=0.8, nl, ru - -app.Get("/", func(c fiber.Ctx) error { - c.AcceptsCharsets("utf-16", "iso-8859-1") - // "iso-8859-1" - - c.AcceptsEncodings("compress", "br") - // "compress" - - c.AcceptsLanguages("pt", "nl", "ru") - // "nl" - // ... -}) -``` - -## App - -Returns the [\*App](ctx.md) reference so you could easily access all application settings. - -```go title="Signature" -func (c Ctx) App() *App -``` - -```go title="Example" -app.Get("/stack", func(c fiber.Ctx) error { - return c.JSON(c.App().Stack()) -}) -``` - -## Append - -Appends the specified **value** to the HTTP response header field. - -:::caution -If the header is **not** already set, it creates the header with the specified value. -::: - -```go title="Signature" -func (c Ctx) Append(field string, values ...string) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.Append("Link", "http://google.com", "http://localhost") - // => Link: http://localhost, http://google.com - - c.Append("Link", "Test") - // => Link: http://localhost, http://google.com, Test - - // ... -}) -``` - -## Attachment - -Sets the HTTP response [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header field to `attachment`. - -```go title="Signature" -func (c Ctx) Attachment(filename ...string) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.Attachment() - // => Content-Disposition: attachment - - c.Attachment("./upload/images/logo.png") - // => Content-Disposition: attachment; filename="logo.png" - // => Content-Type: image/png - - // ... -}) -``` - -## AutoFormat - -Performs content-negotiation on the [Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) HTTP header. It uses [Accepts](ctx.md#accepts) to select a proper format. -The supported content types are `text/html`, `text/plain`, `application/json`, and `application/xml`. -For more flexible content negotiation, use [Format](ctx.md#format). - - -:::info -If the header is **not** specified or there is **no** proper format, **text/plain** is used. -::: - -```go title="Signature" -func (c Ctx) AutoFormat(body any) error -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - // Accept: text/plain - c.AutoFormat("Hello, World!") - // => Hello, World! - - // Accept: text/html - c.AutoFormat("Hello, World!") - // =>

Hello, World!

- - type User struct { - Name string - } - user := User{"John Doe"} - - // Accept: application/json - c.AutoFormat(user) - // => {"Name":"John Doe"} - - // Accept: application/xml - c.AutoFormat(user) - // => John Doe - // .. -}) -``` - -## BaseURL - -Returns the base URL \(**protocol** + **host**\) as a `string`. - -```go title="Signature" -func (c Ctx) BaseURL() string -``` - -```go title="Example" -// GET https://example.com/page#chapter-1 - -app.Get("/", func(c fiber.Ctx) error { - c.BaseURL() // https://example.com - // ... -}) -``` - -## Bind - -Bind is a method that support supports bindings for the request/response body, query parameters, URL parameters, cookies and much more. -It returns a pointer to the [Bind](./bind.md) struct which contains all the methods to bind the request/response data. - -For detailed information check the [Bind](./bind.md) documentation. - -```go title="Signature" -func (c Ctx) Bind() *Bind -``` - -```go title="Example" -app.Post("/", func(c fiber.Ctx) error { - user := new(User) - // Bind the request body to a struct: - return c.Bind().Body(user) -}) -``` - -## Body - -As per the header `Content-Encoding`, this method will try to perform a file decompression from the **body** bytes. In case no `Content-Encoding` header is sent, it will perform as [BodyRaw](#bodyraw). - -```go title="Signature" -func (c Ctx) Body() []byte -``` - -```go title="Example" -// echo 'user=john' | gzip | curl -v -i --data-binary @- -H "Content-Encoding: gzip" http://localhost:8080 - -app.Post("/", func(c fiber.Ctx) error { - // Decompress body from POST request based on the Content-Encoding and return the raw content: - return c.Send(c.Body()) // []byte("user=john") -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## BodyRaw - -Returns the raw request **body**. - -```go title="Signature" -func (c Ctx) BodyRaw() []byte -``` - -```go title="Example" -// curl -X POST http://localhost:8080 -d user=john - -app.Post("/", func(c fiber.Ctx) error { - // Get raw body from POST request: - return c.Send(c.BodyRaw()) // []byte("user=john") -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## ClearCookie - -Expire a client cookie \(_or all cookies if left empty\)_ - -```go title="Signature" -func (c Ctx) ClearCookie(key ...string) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - // Clears all cookies: - c.ClearCookie() - - // Expire specific cookie by name: - c.ClearCookie("user") - - // Expire multiple cookies by names: - c.ClearCookie("token", "session", "track_id", "version") - // ... -}) -``` - -:::caution -Web browsers and other compliant clients will only clear the cookie if the given options are identical to those when creating the cookie, excluding expires and maxAge. ClearCookie will not set these values for you - a technique similar to the one shown below should be used to ensure your cookie is deleted. -::: - -```go title="Example" -app.Get("/set", func(c fiber.Ctx) error { - c.Cookie(&fiber.Cookie{ - Name: "token", - Value: "randomvalue", - Expires: time.Now().Add(24 * time.Hour), - HTTPOnly: true, - SameSite: "lax", - }) - - // ... -}) - -app.Get("/delete", func(c fiber.Ctx) error { - c.Cookie(&fiber.Cookie{ - Name: "token", - // Set expiry date to the past - Expires: time.Now().Add(-(time.Hour * 2)), - HTTPOnly: true, - SameSite: "lax", - }) - - // ... -}) -``` - -## ClientHelloInfo - -ClientHelloInfo contains information from a ClientHello message in order to guide application logic in the GetCertificate and GetConfigForClient callbacks. -You can refer to the [ClientHelloInfo](https://golang.org/pkg/crypto/tls/#ClientHelloInfo) struct documentation for more information on the returned struct. - -```go title="Signature" -func (c Ctx) ClientHelloInfo() *tls.ClientHelloInfo -``` - -```go title="Example" -// GET http://example.com/hello -app.Get("/hello", func(c fiber.Ctx) error { - chi := c.ClientHelloInfo() - // ... -}) -``` - -## Context - -Returns [\*fasthttp.RequestCtx](https://godoc.org/github.com/valyala/fasthttp#RequestCtx) that is compatible with the context.Context interface that requires a deadline, a cancellation signal, and other values across API boundaries. - -```go title="Signature" -func (c Ctx) Context() *fasthttp.RequestCtx -``` - -:::info -Please read the [Fasthttp Documentation](https://pkg.go.dev/github.com/valyala/fasthttp?tab=doc) for more information. -::: - -## Cookie - -Set cookie - -```go title="Signature" -func (c Ctx) Cookie(cookie *Cookie) -``` - -```go -type Cookie struct { - Name string `json:"name"` // The name of the cookie - Value string `json:"value"` // The value of the cookie - Path string `json:"path"` // Specifies a URL path which is allowed to receive the cookie - Domain string `json:"domain"` // Specifies the domain which is allowed to receive the cookie - MaxAge int `json:"max_age"` // The maximum age (in seconds) of the cookie - Expires time.Time `json:"expires"` // The expiration date of the cookie - Secure bool `json:"secure"` // Indicates that the cookie should only be transmitted over a secure HTTPS connection - HTTPOnly bool `json:"http_only"` // Indicates that the cookie is accessible only through the HTTP protocol - SameSite string `json:"same_site"` // Controls whether or not a cookie is sent with cross-site requests - Partitioned bool `json:"partitioned"` // Indicates if the cookie is stored in a partitioned cookie jar - SessionOnly bool `json:"session_only"` // Indicates if the cookie is a session-only cookie -} -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - // Create cookie - cookie := new(fiber.Cookie) - cookie.Name = "john" - cookie.Value = "doe" - cookie.Expires = time.Now().Add(24 * time.Hour) - - // Set cookie - c.Cookie(cookie) - // ... -}) -``` - -:::info - -Partitioned cookies allow partitioning the cookie jar by top-level site, enhancing user privacy by preventing cookies from being shared across different sites. This feature is particularly useful in scenarios where a user interacts with embedded third-party services that should not have access to the main site's cookies. You can check out [CHIPS](https://developers.google.com/privacy-sandbox/3pcd/chips) for more information. - -::: - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - // Create a new partitioned cookie - cookie := new(fiber.Cookie) - cookie.Name = "user_session" - cookie.Value = "abc123" - cookie.Partitioned = true // This cookie will be stored in a separate jar when it's embeded into another website - - // Set the cookie in the response - c.Cookie(cookie) - return c.SendString("Partitioned cookie set") -}) -``` - -## Cookies - -Get cookie value by key, you could pass an optional default value that will be returned if the cookie key does not exist. - -```go title="Signature" -func (c Ctx) Cookies(key string, defaultValue ...string) string -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - // Get cookie by key: - c.Cookies("name") // "john" - c.Cookies("empty", "doe") // "doe" - // ... -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## Download - -Transfers the file from path as an `attachment`. - -Typically, browsers will prompt the user to download. By default, the [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header `filename=` parameter is the file path \(_this typically appears in the browser dialog_\). - -Override this default with the **filename** parameter. - -```go title="Signature" -func (c Ctx) Download(file string, filename ...string) error -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - return c.Download("./files/report-12345.pdf"); - // => Download report-12345.pdf - - return c.Download("./files/report-12345.pdf", "report.pdf"); - // => Download report.pdf -}) -``` - -## Format - -Performs content-negotiation on the [Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) HTTP header. It uses [Accepts](ctx.md#accepts) to select a proper format from the supplied offers. A default handler can be provided by setting the `MediaType` to `"default"`. If no offers match and no default is provided, a 406 (Not Acceptable) response is sent. The Content-Type is automatically set when a handler is selected. - -:::info -If the Accept header is **not** specified, the first handler will be used. -::: - -```go title="Signature" -func (c Ctx) Format(handlers ...ResFmt) error -``` - -```go title="Example" -// Accept: application/json => {"command":"eat","subject":"fruit"} -// Accept: text/plain => Eat Fruit! -// Accept: application/xml => Not Acceptable -app.Get("/no-default", func(c fiber.Ctx) error { - return c.Format( - fiber.ResFmt{"application/json", func(c fiber.Ctx) error { - return c.JSON(fiber.Map{ - "command": "eat", - "subject": "fruit", - }) - }}, - fiber.ResFmt{"text/plain", func(c fiber.Ctx) error { - return c.SendString("Eat Fruit!") - }}, - ) -}) - -// Accept: application/json => {"command":"eat","subject":"fruit"} -// Accept: text/plain => Eat Fruit! -// Accept: application/xml => Eat Fruit! -app.Get("/default", func(c fiber.Ctx) error { - textHandler := func(c fiber.Ctx) error { - return c.SendString("Eat Fruit!") - } - - handlers := []fiber.ResFmt{ - {"application/json", func(c fiber.Ctx) error { - return c.JSON(fiber.Map{ - "command": "eat", - "subject": "fruit", - }) - }}, - {"text/plain", textHandler}, - {"default", textHandler}, - } - - return c.Format(handlers...) -}) -``` - -## FormFile - -MultipartForm files can be retrieved by name, the **first** file from the given key is returned. - -```go title="Signature" -func (c Ctx) FormFile(key string) (*multipart.FileHeader, error) -``` - -```go title="Example" -app.Post("/", func(c fiber.Ctx) error { - // Get first file from form field "document": - file, err := c.FormFile("document") - - // Save file to root directory: - return c.SaveFile(file, fmt.Sprintf("./%s", file.Filename)) -}) -``` - -## FormValue - -Any form values can be retrieved by name, the **first** value from the given key is returned. - -```go title="Signature" -func (c Ctx) FormValue(key string, defaultValue ...string) string -``` - -```go title="Example" -app.Post("/", func(c fiber.Ctx) error { - // Get first value from form field "name": - c.FormValue("name") - // => "john" or "" if not exist - - // .. -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## Fresh - -When the response is still **fresh** in the client's cache **true** is returned, otherwise **false** is returned to indicate that the client cache is now stale and the full response should be sent. - -When a client sends the Cache-Control: no-cache request header to indicate an end-to-end reload request, `Fresh` will return false to make handling these requests transparent. - -Read more on [https://expressjs.com/en/4x/api.html\#req.fresh](https://expressjs.com/en/4x/api.html#req.fresh) - -```go title="Signature" -func (c Ctx) Fresh() bool -``` - -## Get - -Returns the HTTP request header specified by the field. - -:::tip -The match is **case-insensitive**. -::: - -```go title="Signature" -func (c Ctx) Get(key string, defaultValue ...string) string -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.Get("Content-Type") // "text/plain" - c.Get("CoNtEnT-TypE") // "text/plain" - c.Get("something", "john") // "john" - // .. -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## GetReqHeaders - -Returns the HTTP request headers as a map. Since a header can be set multiple times in a single request, the values of the map are slices of strings containing all the different values of the header. - -```go title="Signature" -func (c Ctx) GetReqHeaders() map[string][]string -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## GetRespHeader - -Returns the HTTP response header specified by the field. - -:::tip -The match is **case-insensitive**. -::: - -```go title="Signature" -func (c Ctx) GetRespHeader(key string, defaultValue ...string) string -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.GetRespHeader("X-Request-Id") // "8d7ad5e3-aaf3-450b-a241-2beb887efd54" - c.GetRespHeader("Content-Type") // "text/plain" - c.GetRespHeader("something", "john") // "john" - // .. -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## GetRespHeaders - -Returns the HTTP response headers as a map. Since a header can be set multiple times in a single request, the values of the map are slices of strings containing all the different values of the header. - -```go title="Signature" -func (c Ctx) GetRespHeaders() map[string][]string -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## GetRouteURL - -Generates URLs to named routes, with parameters. URLs are relative, for example: "/user/1831" - -```go title="Signature" -func (c Ctx) GetRouteURL(routeName string, params Map) (string, error) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Home page") -}).Name("home") - -app.Get("/user/:id", func(c fiber.Ctx) error { - return c.SendString(c.Params("id")) -}).Name("user.show") - -app.Get("/test", func(c fiber.Ctx) error { - location, _ := c.GetRouteURL("user.show", fiber.Map{"id": 1}) - return c.SendString(location) -}) - -// /test returns "/user/1" -``` - -## Host - -Returns the host derived from the [Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host) HTTP header. - -In a network context, [`Host`](#host) refers to the combination of a hostname and potentially a port number used for connecting, while [`Hostname`](#hostname) refers specifically to the name assigned to a device on a network, excluding any port information. - -```go title="Signature" -func (c Ctx) Host() string -``` - -```go title="Example" -// GET http://google.com:8080/search - -app.Get("/", func(c fiber.Ctx) error { - c.Host() // "google.com:8080" - c.Hostname() // "google.com" - - // ... -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## Hostname - -Returns the hostname derived from the [Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host) HTTP header. - -```go title="Signature" -func (c Ctx) Hostname() string -``` - -```go title="Example" -// GET http://google.com/search - -app.Get("/", func(c fiber.Ctx) error { - c.Hostname() // "google.com" - - // ... -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## IP - -Returns the remote IP address of the request. - -```go title="Signature" -func (c Ctx) IP() string -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.IP() // "127.0.0.1" - - // ... -}) -``` - -When registering the proxy request header in the fiber app, the ip address of the header is returned [(Fiber configuration)](fiber.md#proxyheader) - -```go -app := fiber.New(fiber.Config{ - ProxyHeader: fiber.HeaderXForwardedFor, -}) -``` - -## IPs - -Returns an array of IP addresses specified in the [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) request header. - -```go title="Signature" -func (c Ctx) IPs() []string -``` - -```go title="Example" -// X-Forwarded-For: proxy1, 127.0.0.1, proxy3 - -app.Get("/", func(c fiber.Ctx) error { - c.IPs() // ["proxy1", "127.0.0.1", "proxy3"] - - // ... -}) -``` - -:::caution -Improper use of the X-Forwarded-For header can be a security risk. For details, see the [Security and privacy concerns](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For#security_and_privacy_concerns) section. -::: - -## Is - -Returns the matching **content type**, if the incoming request’s [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) HTTP header field matches the [MIME type](https://developer.mozilla.org/ru/docs/Web/HTTP/Basics_of_HTTP/MIME_types) specified by the type parameter. - -:::info -If the request has **no** body, it returns **false**. -::: - -```go title="Signature" -func (c Ctx) Is(extension string) bool -``` - -```go title="Example" -// Content-Type: text/html; charset=utf-8 - -app.Get("/", func(c fiber.Ctx) error { - c.Is("html") // true - c.Is(".html") // true - c.Is("json") // false - - // ... -}) -``` - -## IsFromLocal - -Returns true if request came from localhost - -```go title="Signature" -func (c Ctx) IsFromLocal() bool { -``` - -```go title="Example" - -app.Get("/", func(c fiber.Ctx) error { - // If request came from localhost, return true else return false - c.IsFromLocal() - - // ... -}) -``` - -## IsProxyTrusted - -Checks trustworthiness of remote ip. -If [`EnableTrustedProxyCheck`](fiber.md#enabletrustedproxycheck) false, it returns true -IsProxyTrusted can check remote ip by proxy ranges and ip map. - -```go title="Signature" -func (c Ctx) IsProxyTrusted() bool -``` - -```go title="Example" - -app := fiber.New(fiber.Config{ - // EnableTrustedProxyCheck enables the trusted proxy check - EnableTrustedProxyCheck: true, - // TrustedProxies is a list of trusted proxy IP addresses - TrustedProxies: []string{"0.8.0.0", "0.8.0.1"}, -}) - - -app.Get("/", func(c fiber.Ctx) error { - // If request came from trusted proxy, return true else return false - c.IsProxyTrusted() - - // ... -}) - -``` - -## JSON - -Converts any **interface** or **string** to JSON using the [encoding/json](https://pkg.go.dev/encoding/json) package. - -:::info -JSON also sets the content header to the `ctype` parameter. If no `ctype` is passed in, the header is set to `application/json`. -::: - -```go title="Signature" -func (c Ctx) JSON(data any, ctype ...string) error -``` - -```go title="Example" -type SomeStruct struct { - Name string - Age uint8 -} - -app.Get("/json", func(c fiber.Ctx) error { - // Create data struct: - data := SomeStruct{ - Name: "Grame", - Age: 20, - } - - return c.JSON(data) - // => Content-Type: application/json - // => "{"Name": "Grame", "Age": 20}" - - return c.JSON(fiber.Map{ - "name": "Grame", - "age": 20, - }) - // => Content-Type: application/json - // => "{"name": "Grame", "age": 20}" - - return c.JSON(fiber.Map{ - "type": "https://example.com/probs/out-of-credit", - "title": "You do not have enough credit.", - "status": 403, - "detail": "Your current balance is 30, but that costs 50.", - "instance": "/account/12345/msgs/abc", - }, "application/problem+json") - // => Content-Type: application/problem+json - // => "{ - // => "type": "https://example.com/probs/out-of-credit", - // => "title": "You do not have enough credit.", - // => "status": 403, - // => "detail": "Your current balance is 30, but that costs 50.", - // => "instance": "/account/12345/msgs/abc", - // => }" -}) -``` - -## JSONP - -Sends a JSON response with JSONP support. This method is identical to [JSON](ctx.md#json), except that it opts-in to JSONP callback support. By default, the callback name is simply callback. - -Override this by passing a **named string** in the method. - -```go title="Signature" -func (c Ctx) JSONP(data any, callback ...string) error -``` - -```go title="Example" -type SomeStruct struct { - name string - age uint8 -} - -app.Get("/", func(c fiber.Ctx) error { - // Create data struct: - data := SomeStruct{ - name: "Grame", - age: 20, - } - - return c.JSONP(data) - // => callback({"name": "Grame", "age": 20}) - - return c.JSONP(data, "customFunc") - // => customFunc({"name": "Grame", "age": 20}) -}) -``` - -## Links - -Joins the links followed by the property to populate the response’s [Link](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link) HTTP header field. - -```go title="Signature" -func (c Ctx) Links(link ...string) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.Links( - "http://api.example.com/users?page=2", "next", - "http://api.example.com/users?page=5", "last", - ) - // Link: ; rel="next", - // ; rel="last" - - // ... -}) -``` - -## Locals - -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. 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" -func (c Ctx) Locals(key any, value ...any) any -``` - -```go title="Example" - -// keyType is an unexported type for keys defined in this package. -// This prevents collisions with keys defined in other packages. -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 keyType - -app.Use(func(c fiber.Ctx) error { - 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 { - 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) -}) -``` - -An alternative version of the Locals method that takes advantage of Go's generics feature is also available. This version -allows for the manipulation and retrieval of local values within a request's context with a more specific data type. - -```go title="Signature" -func Locals[V any](c Ctx, key any, value ...V) V -``` - -```go title="Example" -app.Use(func(c Ctx) error { - fiber.Locals[string](c, "john", "doe") - fiber.Locals[int](c, "age", 18) - fiber.Locals[bool](c, "isHuman", true) - return c.Next() -}) -app.Get("/test", func(c Ctx) error { - fiber.Locals[string](c, "john") // "doe" - fiber.Locals[int](c, "age") // 18 - fiber.Locals[bool](c, "isHuman") // true - return nil -}) -```` - -Make sure to understand and correctly implement the Locals method in both its standard and generic form for better control -over route-specific data within your application. - -## Location - -Sets the response [Location](https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Location) HTTP header to the specified path parameter. - -```go title="Signature" -func (c Ctx) Location(path string) -``` - -```go title="Example" -app.Post("/", func(c fiber.Ctx) error { - c.Location("http://example.com") - - c.Location("/foo/bar") - - return nil -}) -``` - -## Method - -Returns a string corresponding to the HTTP method of the request: `GET`, `POST`, `PUT`, and so on. -Optionally, you could override the method by passing a string. - -```go title="Signature" -func (c Ctx) Method(override ...string) string -``` - -```go title="Example" -app.Post("/", func(c fiber.Ctx) error { - c.Method() // "POST" - - c.Method("GET") - c.Method() // GET - - // ... -}) -``` - -## MultipartForm - -To access multipart form entries, you can parse the binary with `MultipartForm()`. This returns a `map[string][]string`, so given a key, the value will be a string slice. - -```go title="Signature" -func (c Ctx) MultipartForm() (*multipart.Form, error) -``` - -```go title="Example" -app.Post("/", func(c fiber.Ctx) error { - // Parse the multipart form: - if form, err := c.MultipartForm(); err == nil { - // => *multipart.Form - - if token := form.Value["token"]; len(token) > 0 { - // Get key value: - fmt.Println(token[0]) - } - - // Get all files from "documents" key: - files := form.File["documents"] - // => []*multipart.FileHeader - - // Loop through files: - for _, file := range files { - fmt.Println(file.Filename, file.Size, file.Header["Content-Type"][0]) - // => "tutorial.pdf" 360641 "application/pdf" - - // Save the files to disk: - if err := c.SaveFile(file, fmt.Sprintf("./%s", file.Filename)); err != nil { - return err - } - } - } - - return err -}) -``` - -## Next - -When **Next** is called, it executes the next method in the stack that matches the current route. You can pass an error struct within the method that will end the chaining and call the [error handler](https://docs.gofiber.io/guide/error-handling). - -```go title="Signature" -func (c Ctx) Next() error -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - fmt.Println("1st route!") - return c.Next() -}) - -app.Get("*", func(c fiber.Ctx) error { - fmt.Println("2nd route!") - return c.Next() -}) - -app.Get("/", func(c fiber.Ctx) error { - fmt.Println("3rd route!") - return c.SendString("Hello, World!") -}) -``` - -## OriginalURL - -Returns the original request URL. - -```go title="Signature" -func (c Ctx) OriginalURL() string -``` - -```go title="Example" -// GET http://example.com/search?q=something - -app.Get("/", func(c fiber.Ctx) error { - c.OriginalURL() // "/search?q=something" - - // ... -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -## Params - -Method can be used to get the route parameters, you could pass an optional default value that will be returned if the param key does not exist. - -:::info -Defaults to empty string \(`""`\), if the param **doesn't** exist. -::: - -```go title="Signature" -func (c Ctx) Params(key string, defaultValue ...string) string -``` - -```go title="Example" -// GET http://example.com/user/fenny -app.Get("/user/:name", func(c fiber.Ctx) error { - c.Params("name") // "fenny" - - // ... -}) - -// GET http://example.com/user/fenny/123 -app.Get("/user/*", func(c fiber.Ctx) error { - c.Params("*") // "fenny/123" - c.Params("*1") // "fenny/123" - - // ... -}) -``` - -Unnamed route parameters\(\*, +\) can be fetched by the **character** and the **counter** in the route. - -```go title="Example" -// ROUTE: /v1/*/shop/* -// GET: /v1/brand/4/shop/blue/xs -c.Params("*1") // "brand/4" -c.Params("*2") // "blue/xs" -``` - -For reasons of **downward compatibility**, the first parameter segment for the parameter character can also be accessed without the counter. - -```go title="Example" -app.Get("/v1/*/shop/*", func(c fiber.Ctx) error { - c.Params("*") // outputs the values of the first wildcard segment -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - - -In certain scenarios, it can be useful to have an alternative approach to handle different types of parameters, not -just strings. This can be achieved using a generic Query function known as `Params[V GenericType](c Ctx, key string, defaultValue ...V) V`. -This function is capable of parsing a query string and returning a value of a type that is assumed and specified by `V GenericType`. - -```go title="Signature" -func Params[v GenericType](c Ctx, key string, default value ...V) V -``` - -```go title="Example" - -// Get http://example.com/user/114 -app.Get("/user/:id", func(c fiber.Ctx) error{ - fiber.Params[string](c, "id") // returns "114" as string. - fiber.Params[int](c, "id") // returns 114 as integer - fiber.Params[string](c, "number") // retunrs "" (default string type) - fiber.Params[int](c, "number") // returns 0 (default integer value type) -}) -``` - -The generic Params function supports returning the following data types based on V GenericType: -- Integer: int, int8, int16, int32, int64 -- Unsigned integer: uint, uint8, uint16, uint32, uint64 -- Floating-point numbers: float32, float64 -- Boolean: bool -- String: string -- Byte array: []byte - - -## Path - -Contains the path part of the request URL. Optionally, you could override the path by passing a string. For internal redirects, you might want to call [RestartRouting](ctx.md#restartrouting) instead of [Next](ctx.md#next). - -```go title="Signature" -func (c Ctx) Path(override ...string) string -``` - -```go title="Example" -// GET http://example.com/users?sort=desc - -app.Get("/users", func(c fiber.Ctx) error { - c.Path() // "/users" - - c.Path("/john") - c.Path() // "/john" - - // ... -}) -``` - -## Port - -Returns the remote port of the request. - -```go title="Signature" -func (c Ctx) Port() string -``` - -```go title="Example" -// GET http://example.com:8080 -app.Get("/", func(c fiber.Ctx) error { - c.Port() // "8080" - - // ... -}) -``` - -## Protocol - -Contains the request protocol string: `http` or `https` for **TLS** requests. - -```go title="Signature" -func (c Ctx) Protocol() string -``` - -```go title="Example" -// GET http://example.com - -app.Get("/", func(c fiber.Ctx) error { - c.Protocol() // "http" - - // ... -}) -``` - -## Queries - -Queries is a function that returns an object containing a property for each query string parameter in the route. - -```go title="Signature" -func (c Ctx) Queries() map[string]string -``` - -```go title="Example" -// GET http://example.com/?name=alex&want_pizza=false&id= - -app.Get("/", func(c fiber.Ctx) error { - m := c.Queries() - m["name"] // "alex" - m["want_pizza"] // "false" - m["id"] // "" - // ... -}) -``` - -```go title="Example" -// GET http://example.com/?field1=value1&field1=value2&field2=value3 - -app.Get("/", func (c fiber.Ctx) error { - m := c.Queries() - m["field1"] // "value2" - m["field2"] // value3 -}) -``` - -```go title="Example" -// GET http://example.com/?list_a=1&list_a=2&list_a=3&list_b[]=1&list_b[]=2&list_b[]=3&list_c=1,2,3 - -app.Get("/", func(c fiber.Ctx) error { - m := c.Queries() - m["list_a"] // "3" - m["list_b[]"] // "3" - m["list_c"] // "1,2,3" -}) -``` - -```go title="Example" -// GET /api/posts?filters.author.name=John&filters.category.name=Technology - -app.Get("/", func(c fiber.Ctx) error { - m := c.Queries() - m["filters.author.name"] // John - m["filters.category.name"] // Technology -}) -``` - -```go title="Example" -// GET /api/posts?tags=apple,orange,banana&filters[tags]=apple,orange,banana&filters[category][name]=fruits&filters.tags=apple,orange,banana&filters.category.name=fruits - -app.Get("/", func(c fiber.Ctx) error { - m := c.Queries() - m["tags"] // apple,orange,banana - m["filters[tags]"] // apple,orange,banana - m["filters[category][name]"] // fruits - m["filters.tags"] // apple,orange,banana - m["filters.category.name"] // fruits -}) -``` - -## Query - -This property is an object containing a property for each query string parameter in the route, you could pass an optional default value that will be returned if the query key does not exist. - -:::info -If there is **no** query string, it returns an **empty string**. -::: - -```go title="Signature" -func (c Ctx) Query(key string, defaultValue ...string) string -``` - -```go title="Example" -// GET http://example.com/?order=desc&brand=nike - -app.Get("/", func(c fiber.Ctx) error { - c.Query("order") // "desc" - c.Query("brand") // "nike" - c.Query("empty", "nike") // "nike" - - // ... -}) -``` - -:::info - -Returned value is only valid within the handler. Do not store any references. -Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation) - -::: - -In certain scenarios, it can be useful to have an alternative approach to handle different types of query parameters, not -just strings. This can be achieved using a generic Query function known as `Query[V GenericType](c Ctx, key string, defaultValue ...V) V`. -This function is capable of parsing a query string and returning a value of a type that is assumed and specified by `V GenericType`. - -Here is the signature for the generic Query function: - -```go title="Signature" -func Query[V GenericType](c Ctx, key string, defaultValue ...V) V -``` - -Consider this example: - -```go title="Example" -// GET http://example.com/?page=1&brand=nike&new=true - -app.Get("/", func(c fiber.Ctx) error { - fiber.Query[int](c, "page") // 1 - fiber.Query[string](c, "brand") // "nike" - fiber.Query[bool](c, "new") // true - - // ... -}) -``` - -In this case, `Query[V GenericType](c Ctx, key string, defaultValue ...V) V` can retrieve 'page' as an integer, 'brand' -as a string, and 'new' as a boolean. The function uses the appropriate parsing function for each specified type to ensure -the correct type is returned. This simplifies the retrieval process of different types of query parameters, making your -controller actions cleaner. - -The generic Query function supports returning the following data types based on V GenericType: -- Integer: int, int8, int16, int32, int64 -- Unsigned integer: uint, uint8, uint16, uint32, uint64 -- Floating-point numbers: float32, float64 -- Boolean: bool -- String: string -- Byte array: []byte - -## Range - -A struct containing the type and a slice of ranges will be returned. - -```go title="Signature" -func (c Ctx) Range(size int) (Range, error) -``` - -```go title="Example" -// Range: bytes=500-700, 700-900 -app.Get("/", func(c fiber.Ctx) error { - b := c.Range(1000) - if b.Type == "bytes" { - for r := range r.Ranges { - fmt.Println(r) - // [500, 700] - } - } -}) -``` - -## Redirect - -Returns the Redirect reference. - -For detailed information check the [Redirect](./redirect.md) documentation. - -```go title="Signature" -func (c Ctx) Redirect() *Redirect -``` - -```go title="Example" -app.Get("/coffee", func(c fiber.Ctx) error { - return c.Redirect().To("/teapot") -}) - -app.Get("/teapot", func(c fiber.Ctx) error { - return c.Status(fiber.StatusTeapot).Send("🍡 short and stout 🍡") -}) -``` - - -## Render - -Renders a view with data and sends a `text/html` response. By default `Render` uses the default [**Go Template engine**](https://pkg.go.dev/html/template/). If you want to use another View engine, please take a look at our [**Template middleware**](https://docs.gofiber.io/template). - -```go title="Signature" -func (c Ctx) Render(name string, bind Map, layouts ...string) error -``` - -## Request - -Request return the [\*fasthttp.Request](https://godoc.org/github.com/valyala/fasthttp#Request) pointer - -```go title="Signature" -func (c Ctx) Request() *fasthttp.Request -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.Request().Header.Method() - // => []byte("GET") -}) -``` - -## Response - -Response return the [\*fasthttp.Response](https://godoc.org/github.com/valyala/fasthttp#Response) pointer - -```go title="Signature" -func (c Ctx) Response() *fasthttp.Response -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.Response().BodyWriter().Write([]byte("Hello, World!")) - // => "Hello, World!" - return nil -}) -``` - -## Reset - -Reset the context fields by given request when to use server handlers. - -```go title="Signature" -func (c Ctx) Reset(fctx *fasthttp.RequestCtx) -``` - -It is used outside of the Fiber Handlers to reset the context for the next request. - -## RestartRouting - -Instead of executing the next method when calling [Next](ctx.md#next), **RestartRouting** restarts execution from the first method that matches the current route. This may be helpful after overriding the path, i. e. an internal redirect. Note that handlers might be executed again which could result in an infinite loop. - -```go title="Signature" -func (c Ctx) RestartRouting() error -``` - -```go title="Example" -app.Get("/new", func(c fiber.Ctx) error { - return c.SendString("From /new") -}) - -app.Get("/old", func(c fiber.Ctx) error { - c.Path("/new") - return c.RestartRouting() -}) -``` - -## Route - -Returns the matched [Route](https://pkg.go.dev/github.com/gofiber/fiber?tab=doc#Route) struct. - -```go title="Signature" -func (c Ctx) Route() *Route -``` - -```go title="Example" -// http://localhost:8080/hello - - -app.Get("/hello/:name", func(c fiber.Ctx) error { - r := c.Route() - fmt.Println(r.Method, r.Path, r.Params, r.Handlers) - // GET /hello/:name handler [name] - - // ... -}) -``` - -:::caution -Do not rely on `c.Route()` in middlewares **before** calling `c.Next()` - `c.Route()` returns the **last executed route**. -::: - -```go title="Example" -func MyMiddleware() fiber.Handler { - return func(c fiber.Ctx) error { - beforeNext := c.Route().Path // Will be '/' - err := c.Next() - afterNext := c.Route().Path // Will be '/hello/:name' - return err - } -} -``` - -## SaveFile - -Method is used to save **any** multipart file to disk. - -```go title="Signature" -func (c Ctx) SaveFile(fh *multipart.FileHeader, path string) error -``` - -```go title="Example" -app.Post("/", func(c fiber.Ctx) error { - // Parse the multipart form: - if form, err := c.MultipartForm(); err == nil { - // => *multipart.Form - - // Get all files from "documents" key: - files := form.File["documents"] - // => []*multipart.FileHeader - - // Loop through files: - for _, file := range files { - fmt.Println(file.Filename, file.Size, file.Header["Content-Type"][0]) - // => "tutorial.pdf" 360641 "application/pdf" - - // Save the files to disk: - if err := c.SaveFile(file, fmt.Sprintf("./%s", file.Filename)); err != nil { - return err - } - } - return err - } -}) -``` - -## SaveFileToStorage - -Method is used to save **any** multipart file to an external storage system. - -```go title="Signature" -func (c Ctx) SaveFileToStorage(fileheader *multipart.FileHeader, path string, storage Storage) error -``` - -```go title="Example" -storage := memory.New() - -app.Post("/", func(c fiber.Ctx) error { - // Parse the multipart form: - if form, err := c.MultipartForm(); err == nil { - // => *multipart.Form - - // Get all files from "documents" key: - files := form.File["documents"] - // => []*multipart.FileHeader - - // Loop through files: - for _, file := range files { - fmt.Println(file.Filename, file.Size, file.Header["Content-Type"][0]) - // => "tutorial.pdf" 360641 "application/pdf" - - // Save the files to storage: - if err := c.SaveFileToStorage(file, fmt.Sprintf("./%s", file.Filename), storage); err != nil { - return err - } - } - return err - } -}) -``` - -## Schema - -Contains the request protocol string: http or https for TLS requests. - -:::info -Please use [`Config.EnableTrustedProxyCheck`](fiber.md#enabletrustedproxycheck) to prevent header spoofing, in case when your app is behind the proxy. -::: - -```go title="Signature" -func (c Ctx) Schema() string -``` - -```go title="Example" -// GET http://example.com -app.Get("/", func(c fiber.Ctx) error { - c.Schema() // "http" - - // ... -}) -``` - -## Secure - -A boolean property that is `true` , if a **TLS** connection is established. - -```go title="Signature" -func (c Ctx) Secure() bool -``` - -```go title="Example" -// Secure() method is equivalent to: -c.Protocol() == "https" -``` - -## Send - -Sets the HTTP response body. - -```go title="Signature" -func (c Ctx) Send(body []byte) error -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - return c.Send([]byte("Hello, World!")) // => "Hello, World!" -}) -``` - -Fiber also provides `SendString` and `SendStream` methods for raw inputs. - -:::tip -Use this if you **don't need** type assertion, recommended for **faster** performance. -::: - -```go title="Signature" -func (c Ctx) SendString(body string) error -func (c Ctx) SendStream(stream io.Reader, size ...int) error -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") - // => "Hello, World!" - - return c.SendStream(bytes.NewReader([]byte("Hello, World!"))) - // => "Hello, World!" -}) -``` - -## SendFile - -Transfers the file from the given path. Sets the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) response HTTP header field based on the **filenames** extension. - -```go title="Config" title="Config" -// SendFile defines configuration options when to transfer file with SendFile. -type SendFile struct { - // FS is the file system to serve the static files from. - // You can use interfaces compatible with fs.FS like embed.FS, os.DirFS etc. - // - // Optional. Default: nil - FS fs.FS - - // When set to true, the server tries minimizing CPU usage by caching compressed files. - // This works differently than the github.com/gofiber/compression middleware. - // You have to set Content-Encoding header to compress the file. - // Available compression methods are gzip, br, and zstd. - // - // Optional. Default value false - Compress bool `json:"compress"` - - // When set to true, enables byte range requests. - // - // Optional. Default value false - ByteRange bool `json:"byte_range"` - - // When set to true, enables direct download. - // - // Optional. Default: false. - Download bool `json:"download"` - - // Expiration duration for inactive file handlers. - // Use a negative time.Duration to disable it. - // - // Optional. Default value 10 * time.Second. - CacheDuration time.Duration `json:"cache_duration"` - - // The value for the Cache-Control HTTP-header - // that is set on the file response. MaxAge is defined in seconds. - // - // Optional. Default value 0. - MaxAge int `json:"max_age"` -} -``` - -```go title="Signature" title="Signature" -func (c Ctx) SendFile(file string, config ...SendFile) error -``` - -```go title="Example" -app.Get("/not-found", func(c fiber.Ctx) error { - return c.SendFile("./public/404.html"); - - // Disable compression - return c.SendFile("./static/index.html", SendFile{ - Compress: false, - }); -}) -``` - -:::info -If the file contains an url specific character you have to escape it before passing the file path into the `sendFile` function. -::: - -```go title="Example" -app.Get("/file-with-url-chars", func(c fiber.Ctx) error { - return c.SendFile(url.PathEscape("hash_sign_#.txt")) -}) -``` - -:::info -You can set `CacheDuration` config property to `-1` to disable caching. -::: - -```go title="Example" -app.Get("/file", func(c fiber.Ctx) error { - return c.SendFile("style.css", SendFile{ - CacheDuration: -1, - }) -}) -``` - -:::info -You can use multiple SendFile with different configurations in single route. Fiber creates different filesystem handler per config. -::: - -```go title="Example" -app.Get("/file", func(c fiber.Ctx) error { - switch c.Query("config") { - case "filesystem": - return c.SendFile("style.css", SendFile{ - FS: os.DirFS(".") - }) - case "filesystem-compress": - return c.SendFile("style.css", SendFile{ - FS: os.DirFS("."), - Compress: true, - }) - case "compress": - return c.SendFile("style.css", SendFile{ - Compress: true, - }) - default: - return c.SendFile("style.css") - } - - return nil -}) -``` - -:::info -For sending multiple files from embedded file system [this functionality](../middleware/static.md#serving-files-using-embedfs) can be used -::: - -## SendStatus - -Sets the status code and the correct status message in the body, if the response body is **empty**. - -:::tip -You can find all used status codes and messages [here](https://github.com/gofiber/fiber/blob/dffab20bcdf4f3597d2c74633a7705a517d2c8c2/utils.go#L183-L244). -::: - -```go title="Signature" -func (c Ctx) SendStatus(status int) error -``` - -```go title="Example" -app.Get("/not-found", func(c fiber.Ctx) error { - return c.SendStatus(415) - // => 415 "Unsupported Media Type" - - c.SendString("Hello, World!") - return c.SendStatus(415) - // => 415 "Hello, World!" -}) -``` - -## SendStream - -Sets response body to a stream of data and add optional body size. - -```go title="Signature" -func (c Ctx) SendStream(stream io.Reader, size ...int) error -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - return c.SendStream(bytes.NewReader([]byte("Hello, World!"))) - // => "Hello, World!" -}) -``` - -## SendString - -Sets the response body to a string. - -```go title="Signature" -func (c Ctx) SendString(body string) error -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") - // => "Hello, World!" -}) -``` - -## Set - -Sets the response’s HTTP header field to the specified `key`, `value`. - -```go title="Signature" -func (c Ctx) Set(key string, val string) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.Set("Content-Type", "text/plain") - // => "Content-type: text/plain" - - // ... -}) -``` - -## SetUserContext - -Sets the user specified implementation for context interface. - -```go title="Signature" -func (c Ctx) SetUserContext(ctx context.Context) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - ctx := context.Background() - c.SetUserContext(ctx) - // Here ctx could be any context implementation - - // ... -}) -``` - -## Stale - -[https://expressjs.com/en/4x/api.html\#req.stale](https://expressjs.com/en/4x/api.html#req.stale) - -```go title="Signature" -func (c Ctx) Stale() bool -``` - -## Status - -Sets the HTTP status for the response. - -:::info -Method is a **chainable**. -::: - -```go title="Signature" -func (c Ctx) Status(status int) Ctx -``` - -```go title="Example" -app.Get("/fiber", func(c fiber.Ctx) error { - c.Status(fiber.StatusOK) - return nil -} - -app.Get("/hello", func(c fiber.Ctx) error { - return c.Status(fiber.StatusBadRequest).SendString("Bad Request") -} - -app.Get("/world", func(c fiber.Ctx) error { - return c.Status(fiber.StatusNotFound).SendFile("./public/gopher.png") -}) -``` - -## String - -Returns unique string representation of the ctx. - -```go title="Signature" -func (c Ctx) String() string -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.String() // => "#0000000100000001 - 127.0.0.1:3000 <-> 127.0.0.1:61516 - GET http://localhost:3000/" - - // ... -}) -``` - -## Subdomains - -Returns a string slice of subdomains in the domain name of the request. - -The application property subdomain offset, which defaults to `2`, is used for determining the beginning of the subdomain segments. - -```go title="Signature" -func (c Ctx) Subdomains(offset ...int) []string -``` - -```go title="Example" -// Host: "tobi.ferrets.example.com" - -app.Get("/", func(c fiber.Ctx) error { - c.Subdomains() // ["ferrets", "tobi"] - c.Subdomains(1) // ["tobi"] - - // ... -}) -``` - -## Type - -Sets the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) HTTP header to the MIME type listed [here](https://github.com/nginx/nginx/blob/master/conf/mime.types) specified by the file **extension**. - -:::info -Method is a **chainable**. -::: - -```go title="Signature" -func (c Ctx) Type(ext string, charset ...string) Ctx -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.Type(".html") // => "text/html" - c.Type("html") // => "text/html" - c.Type("png") // => "image/png" - - c.Type("json", "utf-8") // => "application/json; charset=utf-8" - - // ... -}) -``` - -## UserContext - -UserContext returns a context implementation that was set by user earlier -or returns a non-nil, empty context, if it was not set earlier. - -```go title="Signature" -func (c Ctx) UserContext() context.Context -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - ctx := c.UserContext() - // ctx is context implementation set by user - - // ... -}) -``` - -## Vary - -Adds the given header field to the [Vary](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary) response header. This will append the header, if not already listed, otherwise leaves it listed in the current location. - -:::info -Multiple fields are **allowed**. -::: - -```go title="Signature" -func (c Ctx) Vary(fields ...string) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.Vary("Origin") // => Vary: Origin - c.Vary("User-Agent") // => Vary: Origin, User-Agent - - // No duplicates - c.Vary("Origin") // => Vary: Origin, User-Agent - - c.Vary("Accept-Encoding", "Accept") - // => Vary: Origin, User-Agent, Accept-Encoding, Accept - - // ... -}) -``` - -## ViewBind - -Add vars to default view var map binding to template engine. -Variables are read by the Render method and may be overwritten. - -```go title="Signature" -func (c Ctx) ViewBind(vars Map) error -``` - -```go title="Example" -app.Use(func(c fiber.Ctx) error { - c.ViewBind(fiber.Map{ - "Title": "Hello, World!", - }) -}) - -app.Get("/", func(c fiber.Ctx) error { - return c.Render("xxx.tmpl", fiber.Map{}) // Render will use Title variable -}) -``` - -## Write - -Write adopts the Writer interface - -```go title="Signature" -func (c Ctx) Write(p []byte) (n int, err error) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.Write([]byte("Hello, World!")) // => "Hello, World!" - - fmt.Fprintf(c, "%s\n", "Hello, World!") // "Hello, World!Hello, World!" -}) -``` - -## Writef - -Writef adopts the string with variables - -```go title="Signature" -func (c Ctx) Writef(f string, a ...any) (n int, err error) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - world := "World!" - c.Writef("Hello, %s", world) // => "Hello, World!" - - fmt.Fprintf(c, "%s\n", "Hello, World!") // "Hello, World!Hello, World!" -}) -``` - -## WriteString - -WriteString adopts the string - -```go title="Signature" -func (c Ctx) WriteString(s string) (n int, err error) -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - c.WriteString("Hello, World!") // => "Hello, World!" - - fmt.Fprintf(c, "%s\n", "Hello, World!") // "Hello, World!Hello, World!" -}) -``` - -## XHR - -A Boolean property, that is `true`, if the request’s [X-Requested-With](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) header field is [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest), indicating that the request was issued by a client library \(such as [jQuery](https://api.jquery.com/jQuery.ajax/)\). - -```go title="Signature" -func (c Ctx) XHR() bool -``` - -```go title="Example" -// X-Requested-With: XMLHttpRequest - -app.Get("/", func(c fiber.Ctx) error { - c.XHR() // true - - // ... -}) -``` - -## XML - -Converts any **interface** or **string** to XML using the standard `encoding/xml` package. - -:::info -XML also sets the content header to **application/xml**. -::: - -```go title="Signature" -func (c Ctx) XML(data any) error -``` - -```go title="Example" -type SomeStruct struct { - XMLName xml.Name `xml:"Fiber"` - Name string `xml:"Name"` - Age uint8 `xml:"Age"` -} - -app.Get("/", func(c fiber.Ctx) error { - // Create data struct: - data := SomeStruct{ - Name: "Grame", - Age: 20, - } - - return c.XML(data) - // - // Grame - // 20 - // -}) -``` diff --git a/versioned_docs/version-v3.x/api/fiber.md b/versioned_docs/version-v3.x/api/fiber.md deleted file mode 100644 index 08d8b6ae829..00000000000 --- a/versioned_docs/version-v3.x/api/fiber.md +++ /dev/null @@ -1,260 +0,0 @@ ---- -id: fiber -title: πŸ“¦ Fiber -description: Fiber represents the fiber package where you start to create an instance. -sidebar_position: 1 ---- - -import Reference from '@site/src/components/reference'; - -## Server start - -### New - -This method creates a new **App** named instance. You can pass optional [config](#config) when creating a new instance. - -```go title="Signature" -func New(config ...Config) *App -``` - -```go title="Example" -// Default config -app := fiber.New() - -// ... -``` - -### Config - -You can pass an optional Config when creating a new Fiber instance. - -```go title="Example" -// Custom config -app := fiber.New(fiber.Config{ - CaseSensitive: true, - StrictRouting: true, - ServerHeader: "Fiber", - AppName: "Test App v1.0.1", -}) - -// ... -``` - -#### Config fields - -| Property | Type | Description | Default | -|---------------------------------------------------------------------------------------|-------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------| -| AppName | `string` | This allows to setup app name for the app | `""` | -| BodyLimit | `int` | Sets the maximum allowed size for a request body, if the size exceeds the configured limit, it sends `413 - Request Entity Too Large` response. | `4 * 1024 * 1024` | -| CaseSensitive | `bool` | When enabled, `/Foo` and `/foo` are different routes. When disabled, `/Foo`and `/foo` are treated the same. | `false` | -| ColorScheme | [`Colors`](https://github.com/gofiber/fiber/blob/master/color.go) | You can define custom color scheme. They'll be used for startup message, route list and some middlewares. | [`DefaultColors`](https://github.com/gofiber/fiber/blob/master/color.go) | -| CompressedFileSuffixes | `map[string]string` | Adds a suffix to the original file name and tries saving the resulting compressed file under the new file name. | `{"gzip": ".fiber.gz", "br": ".fiber.br", "zstd": ".fiber.zst"}` | -| Concurrency | `int` | Maximum number of concurrent connections. | `256 * 1024` | -| DisableDefaultContentType | `bool` | When set to true, causes the default Content-Type header to be excluded from the Response. | `false` | -| DisableDefaultDate | `bool` | When set to true causes the default date header to be excluded from the response. | `false` | -| DisableHeaderNormalizing | `bool` | By default all header names are normalized: conteNT-tYPE -> Content-Type | `false` | -| DisableKeepalive | `bool` | Disable keep-alive connections, the server will close incoming connections after sending the first response to the client | `false` | -| DisablePreParseMultipartForm | `bool` | Will not pre parse Multipart Form data if set to true. This option is useful for servers that desire to treat multipart form data as a binary blob, or choose when to parse the data. | `false` | -| EnableIPValidation | `bool` | If set to true, `c.IP()` and `c.IPs()` will validate IP addresses before returning them. Also, `c.IP()` will return only the first valid IP rather than just the raw header value that may be a comma separated string.

**WARNING:** There is a small performance cost to doing this validation. Keep disabled if speed is your only concern and your application is behind a trusted proxy that already validates this header. | `false` | -| EnableSplittingOnParsers | `bool` | EnableSplittingOnParsers splits the query/body/header parameters by comma when it's true.

For example, you can use it to parse multiple values from a query parameter like this: `/api?foo=bar,baz == foo[]=bar&foo[]=baz` | `false` | -| EnableTrustedProxyCheck | `bool` | When set to true, fiber will check whether proxy is trusted, using TrustedProxies list.

By default `c.Protocol()` will get value from X-Forwarded-Proto, X-Forwarded-Protocol, X-Forwarded-Ssl or X-Url-Scheme header, `c.IP()` will get value from `ProxyHeader` header, `c.Hostname()` will get value from X-Forwarded-Host header.
If `EnableTrustedProxyCheck` is true, and `RemoteIP` is in the list of `TrustedProxies` `c.Protocol()`, `c.IP()`, and `c.Hostname()` will have the same behaviour when `EnableTrustedProxyCheck` disabled, if `RemoteIP` isn't in the list, `c.Protocol()` will return https in case when tls connection is handled by the app, or http otherwise, `c.IP()` will return RemoteIP() from fasthttp context, `c.Hostname()` will return `fasthttp.Request.URI().Host()` | `false` | -| ErrorHandler | `ErrorHandler` | ErrorHandler is executed when an error is returned from fiber.Handler. Mounted fiber error handlers are retained by the top-level app and applied on prefix associated requests. | `DefaultErrorHandler` | -| GETOnly | `bool` | Rejects all non-GET requests if set to true. This option is useful as anti-DoS protection for servers accepting only GET requests. The request size is limited by ReadBufferSize if GETOnly is set. | `false` | -| IdleTimeout | `time.Duration` | The maximum amount of time to wait for the next request when keep-alive is enabled. If IdleTimeout is zero, the value of ReadTimeout is used. | `nil` | -| Immutable | `bool` | When enabled, all values returned by context methods are immutable. By default, they are valid until you return from the handler; see issue [\#185](https://github.com/gofiber/fiber/issues/185). | `false` | -| JSONDecoder | `utils.JSONUnmarshal` | Allowing for flexibility in using another json library for decoding. | `json.Unmarshal` | -| JSONEncoder | `utils.JSONMarshal` | Allowing for flexibility in using another json library for encoding. | `json.Marshal` | -| PassLocalsToViews | `bool` | PassLocalsToViews Enables passing of the locals set on a fiber.Ctx to the template engine. See our **Template Middleware** for supported engines. | `false` | -| ProxyHeader | `string` | This will enable `c.IP()` to return the value of the given header key. By default `c.IP()`will return the Remote IP from the TCP connection, this property can be useful if you are behind a load balancer e.g. _X-Forwarded-\*_. | `""` | -| ReadBufferSize | `int` | per-connection buffer size for requests' reading. This also limits the maximum header size. Increase this buffer if your clients send multi-KB RequestURIs and/or multi-KB headers \(for example, BIG cookies\). | `4096` | -| ReadTimeout | `time.Duration` | The amount of time allowed to read the full request, including the body. The default timeout is unlimited. | `nil` | -| ReduceMemoryUsage | `bool` | Aggressively reduces memory usage at the cost of higher CPU usage if set to true. | `false` | -| RequestMethods | `[]string` | RequestMethods provides customizibility for HTTP methods. You can add/remove methods as you wish. | `DefaultMethods` | -| ServerHeader | `string` | Enables the `Server` HTTP header with the given value. | `""` | -| StreamRequestBody | `bool` | StreamRequestBody enables request body streaming, and calls the handler sooner when given body is larger than the current limit. | `false` | -| StrictRouting | `bool` | When enabled, the router treats `/foo` and `/foo/` as different. Otherwise, the router treats `/foo` and `/foo/` as the same. | `false` | -| StructValidator | `StructValidator` | If you want to validate header/form/query... automatically when to bind, you can define struct validator. Fiber doesn't have default validator, so it'll skip validator step if you don't use any validator. | `nil` | -| TrustedProxies | `[]string` | Contains the list of trusted proxy IP's. Look at `EnableTrustedProxyCheck` doc.

It can take IP or IP range addresses. | `nil` | -| UnescapePath | `bool` | Converts all encoded characters in the route back before setting the path for the context, so that the routing can also work with URL encoded special characters | `false` | -| Views | `Views` | Views is the interface that wraps the Render function. See our **Template Middleware** for supported engines. | `nil` | -| ViewsLayout | `string` | Views Layout is the global layout for all template render until override on Render function. See our **Template Middleware** for supported engines. | `""` | -| WriteBufferSize | `int` | Per-connection buffer size for responses' writing. | `4096` | -| WriteTimeout | `time.Duration` | The maximum duration before timing out writes of the response. The default timeout is unlimited. | `nil` | -| XMLEncoder | `utils.XMLMarshal` | Allowing for flexibility in using another XML library for encoding. | `xml.Marshal` | - - -## Server listening - -### Config - -You can pass an optional ListenConfig when calling the [`Listen`](#listen) or [`Listener`](#listener) method. - -```go title="Example" -// Custom config -app.Listen(":8080", fiber.ListenConfig{ - EnablePrefork: true, - DisableStartupMessage: true, -}) -``` - -#### Config fields - -| Property | Type | Description | Default | -|-------------------------------------------------------------------------|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|---------| -| BeforeServeFunc | `func(app *App) error` | Allows customizing and accessing fiber app before serving the app. | `nil` | -| CertClientFile | `string` | Path of the client certificate. If you want to use mTLS, you must enter this field. | `""` | -| CertFile | `string` | Path of the certificate file. If you want to use TLS, you must enter this field. | `""` | -| CertKeyFile | `string` | Path of the certificate's private key. If you want to use TLS, you must enter this field. | `""` | -| DisableStartupMessage | `bool` | When set to true, it will not print out the Β«FiberΒ» ASCII art and listening address. | `false` | -| EnablePrefork | `bool` | When set to true, this will spawn multiple Go processes listening on the same port. | `false` | -| EnablePrintRoutes | `bool` | If set to true, will print all routes with their method, path, and handler. | `false` | -| GracefulContext | `context.Context` | Field to shutdown Fiber by given context gracefully. | `nil` | -| ListenerAddrFunc | `func(addr net.Addr)` | Allows accessing and customizing `net.Listener`. | `nil` | -| ListenerNetwork | `string` | Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only). WARNING: When prefork is set to true, only "tcp4" and "tcp6" can be chosen. | `tcp4` | -| OnShutdownError | `func(err error)` | Allows to customize error behavior when gracefully shutting down the server by given signal. Prints error with `log.Fatalf()` | `nil` | -| OnShutdownSuccess | `func()` | Allows to customize success behavior when gracefully shutting down the server by given signal. | `nil` | -| TLSConfigFunc | `func(tlsConfig *tls.Config)` | Allows customizing `tls.Config` as you want. | `nil` | - - -### Listen - -Listen serves HTTP requests from the given address. - -```go title="Signature" -func (app *App) Listen(addr string, config ...ListenConfig) error -``` - -```go title="Examples" -// Listen on port :8080 -app.Listen(":8080") - -// Listen on port :8080 with Prefork -app.Listen(":8080", fiber.ListenConfig{EnablePrefork: true}) - -// Custom host -app.Listen("127.0.0.1:8080") -``` - -#### Prefork - -Prefork is a feature that allows you to spawn multiple Go processes listening on the same port. This can be useful for scaling across multiple CPU cores. - -```go title="Examples" -app.Listen(":8080", fiber.ListenConfig{EnablePrefork: true}) -``` - -This distributes the incoming connections between the spawned processes and allows more requests to be handled simultaneously. - -#### TLS - -TLS serves HTTPs requests from the given address using certFile and keyFile paths to as TLS certificate and key file. - -```go title="Examples" -app.Listen(":443", fiber.ListenConfig{CertFile: "./cert.pem", CertKeyFile: "./cert.key"}) -``` - -#### TLS with certificate - -```go title="Examples" -app.Listen(":443", fiber.ListenConfig{CertClientFile: "./ca-chain-cert.pem"}) -``` - -#### TLS with certFile, keyFile and clientCertFile - -```go title="Examples" -app.Listen(":443", fiber.ListenConfig{CertFile: "./cert.pem", CertKeyFile: "./cert.key", CertClientFile: "./ca-chain-cert.pem"}) -``` - -### Listener - -You can pass your own [`net.Listener`](https://pkg.go.dev/net/#Listener) using the `Listener` method. This method can be used to enable **TLS/HTTPS** with a custom tls.Config. - -```go title="Signature" -func (app *App) Listener(ln net.Listener, config ...ListenConfig) error -``` - -```go title="Examples" -ln, _ := net.Listen("tcp", ":3000") - -cer, _:= tls.LoadX509KeyPair("server.crt", "server.key") - -ln = tls.NewListener(ln, &tls.Config{Certificates: []tls.Certificate{cer}}) - -app.Listener(ln) -``` - -## Server - -Server returns the underlying [fasthttp server](https://godoc.org/github.com/valyala/fasthttp#Server) - -```go title="Signature" -func (app *App) Server() *fasthttp.Server -``` - -```go title="Examples" -func main() { - app := fiber.New() - - app.Server().MaxConnsPerIP = 1 - - // ... -} -``` - -## Server Shutdown - -Shutdown gracefully shuts down the server without interrupting any active connections. Shutdown works by first closing all open listeners and then waits indefinitely for all connections to return to idle before shutting down. - -ShutdownWithTimeout will forcefully close any active connections after the timeout expires. - -ShutdownWithContext shuts down the server including by force if the context's deadline is exceeded. - -```go -func (app *App) Shutdown() error -func (app *App) ShutdownWithTimeout(timeout time.Duration) error -func (app *App) ShutdownWithContext(ctx context.Context) error -``` - - -## Helper functions - -### NewError - -NewError creates a new HTTPError instance with an optional message. - -```go title="Signature" -func NewError(code int, message ...string) *Error -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - return fiber.NewError(782, "Custom error message") -}) -``` - -### IsChild - -IsChild determines if the current process is a result of Prefork. - -```go title="Signature" -func IsChild() bool -``` - -```go title="Example" -// Config app -app := fiber.New() - -app.Get("/", func(c fiber.Ctx) error { - if !fiber.IsChild() { - fmt.Println("I'm the parent process") - } else { - fmt.Println("I'm a child process") - } - return c.SendString("Hello, World!") -}) - -// ... - -// With prefork enabled, the parent process will spawn child processes -app.Listen(":8080", fiber.ListenConfig{EnablePrefork: true}) -``` diff --git a/versioned_docs/version-v3.x/api/hooks.md b/versioned_docs/version-v3.x/api/hooks.md deleted file mode 100644 index 8717ba58514..00000000000 --- a/versioned_docs/version-v3.x/api/hooks.md +++ /dev/null @@ -1,218 +0,0 @@ ---- -id: hooks -title: 🎣 Hooks -sidebar_position: 7 ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -With Fiber v2.30.0, you can execute custom user functions when to run some methods. Here is a list of this hooks: -- [OnRoute](#onroute) -- [OnName](#onname) -- [OnGroup](#ongroup) -- [OnGroupName](#ongroupname) -- [OnListen](#onlisten) -- [OnFork](#onfork) -- [OnShutdown](#onshutdown) -- [OnMount](#onmount) - -## Constants -```go -// Handlers define a function to create hooks for Fiber. -type OnRouteHandler = func(Route) error -type OnNameHandler = OnRouteHandler -type OnGroupHandler = func(Group) error -type OnGroupNameHandler = OnGroupHandler -type OnListenHandler = func(ListenData) error -type OnForkHandler = func(int) error -type OnShutdownHandler = func() error -type OnMountHandler = func(*App) error -``` - -## OnRoute - -OnRoute is a hook to execute user functions on each route registeration. Also you can get route properties by **route** parameter. - -```go title="Signature" -func (h *Hooks) OnRoute(handler ...OnRouteHandler) -``` - -## OnName - -OnName is a hook to execute user functions on each route naming. Also you can get route properties by **route** parameter. - -:::caution -OnName only works with naming routes, not groups. -::: - -```go title="Signature" -func (h *Hooks) OnName(handler ...OnNameHandler) -``` - - - - -```go -package main - -import ( - "fmt" - - "github.com/gofiber/fiber/v3" -) - -func main() { - app := fiber.New() - - app.Get("/", func(c fiber.Ctx) error { - return c.SendString(c.Route().Name) - }).Name("index") - - app.Hooks().OnName(func(r fiber.Route) error { - fmt.Print("Name: " + r.Name + ", ") - - return nil - }) - - app.Hooks().OnName(func(r fiber.Route) error { - fmt.Print("Method: " + r.Method + "\n") - - return nil - }) - - app.Get("/add/user", func(c fiber.Ctx) error { - return c.SendString(c.Route().Name) - }).Name("addUser") - - app.Delete("/destroy/user", func(c fiber.Ctx) error { - return c.SendString(c.Route().Name) - }).Name("destroyUser") - - app.Listen(":5000") -} - -// Results: -// Name: addUser, Method: GET -// Name: destroyUser, Method: DELETE -``` - - - -## OnGroup - -OnGroup is a hook to execute user functions on each group registeration. Also you can get group properties by **group** parameter. - -```go title="Signature" -func (h *Hooks) OnGroup(handler ...OnGroupHandler) -``` - -## OnGroupName - -OnGroupName is a hook to execute user functions on each group naming. Also you can get group properties by **group** parameter. - -:::caution -OnGroupName only works with naming groups, not routes. -::: - -```go title="Signature" -func (h *Hooks) OnGroupName(handler ...OnGroupNameHandler) -``` - -## OnListen - -OnListen is a hook to execute user functions on Listen, ListenTLS, Listener. - -```go title="Signature" -func (h *Hooks) OnListen(handler ...OnListenHandler) -``` - - - - -```go -app := fiber.New(fiber.Config{ - DisableStartupMessage: true, -}) - -app.Hooks().OnListen(func(listenData fiber.ListenData) error { - if fiber.IsChild() { - return nil - } - scheme := "http" - if data.TLS { - scheme = "https" - } - log.Println(scheme + "://" + listenData.Host + ":" + listenData.Port) - return nil -}) - -app.Listen(":5000") -``` - - - - -## OnFork - -OnFork is a hook to execute user functions on Fork. - -```go title="Signature" -func (h *Hooks) OnFork(handler ...OnForkHandler) -``` - -## OnShutdown - -OnShutdown is a hook to execute user functions after Shutdown. - -```go title="Signature" -func (h *Hooks) OnShutdown(handler ...OnShutdownHandler) -``` - -## OnMount - -OnMount is a hook to execute user function after mounting process. The mount event is fired when sub-app is mounted on a parent app. The parent app is passed as a parameter. It works for app and group mounting. - -```go title="Signature" -func (h *Hooks) OnMount(handler ...OnMountHandler) -``` - - - - -```go -package main - -import ( - "fmt" - - "github.com/gofiber/fiber/v3" -) - -func main() { - app := New() - app.Get("/", testSimpleHandler).Name("x") - - subApp := New() - subApp.Get("/test", testSimpleHandler) - - subApp.Hooks().OnMount(func(parent *fiber.App) error { - fmt.Print("Mount path of parent app: "+parent.MountPath()) - // ... - - return nil - }) - - app.Mount("/sub", subApp) -} - -// Result: -// Mount path of parent app: -``` - - - - - -:::caution -OnName/OnRoute/OnGroup/OnGroupName hooks are mount-sensitive. If you use one of these routes on sub app and you mount it; paths of routes and groups will start with mount prefix. diff --git a/versioned_docs/version-v3.x/api/log.md b/versioned_docs/version-v3.x/api/log.md deleted file mode 100644 index e53d6d4b0a4..00000000000 --- a/versioned_docs/version-v3.x/api/log.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -id: log -title: πŸ“ƒ Log -description: Fiber's built-in log package -sidebar_position: 6 ---- - -We can use logs to observe program behavior, diagnose problems, or configure corresponding alarms. -And defining a well structured log can improve search efficiency and facilitate handling of problems. - -Fiber provides a default way to print logs in the standard output. -It also provides several global functions, such as `log.Info`, `log.Errorf`, `log.Warnw`, etc. - -## Log levels - -```go -const ( - LevelTrace Level = iota - LevelDebug - LevelInfo - LevelWarn - LevelError - LevelFatal - LevelPanic -) -``` - -## Custom log - -Fiber provides the `AllLogger` interface for adapting the various log libraries. - -```go -type CommonLogger interface { - Logger - FormatLogger - WithLogger -} - -type AllLogger interface { - CommonLogger - ControlLogger - WithLogger -} -``` - -## Print log -Note: The method of calling the Fatal level will interrupt the program running after printing the log, please use it with caution. -Directly print logs of different levels, which will be entered into messageKey, the default is msg. - -```go -log.Info("Hello, World!") -log.Debug("Are you OK?") -log.Info("42 is the answer to life, the universe, and everything") -log.Warn("We are under attack!") -log.Error("Houston, we have a problem.") -log.Fatal("So Long, and Thanks for All the Fislog.") -log.Panic("The system is down.") -``` -Format and print logs of different levels, all methods end with f - -```go -log.Debugf("Hello %s", "boy") -log.Infof("%d is the answer to life, the universe, and everything", 233) -log.Warnf("We are under attack %s!", "boss") -log.Errorf("%s, we have a problem.", "Master Shifu") -log.Fatalf("So Long, and Thanks for All the %s.", "banana") -``` - -Print a message with the key and value, or `KEYVALS UNPAIRED` if the key and value are not a pair. - -```go -log.Debugw("", "Hello", "boy") -log.Infow("", "number", 233) -log.Warnw("", "job", "boss") -log.Errorw("", "name", "Master Shifu") -log.Fatalw("", "fruit", "banana") -``` - -## Global log -If you are in a project and just want to use a simple log function that can be printed at any time in the global, we provide a global log. - -```go -import "github.com/gofiber/fiber/v3/log" - -log.Info("info") -log.Warn("warn") -``` - -The above is using the default `log.DefaultLogger` standard output. -You can also find an already implemented adaptation under contrib, or use your own implemented Logger and use `log.SetLogger` to set the global log logger. - -```go -import ( - "log" - fiberlog "github.com/gofiber/fiber/v3/log" -) - -var _ log.AllLogger = (*customLogger)(nil) - -type customLogger struct { - stdlog *log.Logger -} - -// ... -// inject your custom logger -fiberlog.SetLogger(customLogger) -``` - -## Set Level -`log.SetLevel` sets the level of logs below which logs will not be output. -The default logger is LevelTrace. - -Note that this method is not **concurrent-safe**. - -```go -import "github.com/gofiber/fiber/v3/log" - -log.SetLevel(log.LevelInfo) -``` -## Set output - -`log.SetOutput` sets the output destination of the logger. The default logger types the log in the console. - -```go -var logger AllLogger = &defaultLogger{ - stdlog: log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds), - depth: 4, -} -``` - -Set the output destination to the file. - -```go -// Output to ./test.log file -f, err := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) -if err != nil { - return -} -log.SetOutput(f) -``` -Set the output destination to the console and file. - -```go -// Output to ./test.log file -file, _ := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) -iw := io.MultiWriter(os.Stdout, file) -log.SetOutput(iw) -``` -## Bind context -Set the context, using the following method will return a `CommonLogger` instance bound to the specified context -```go -commonLogger := log.WithContext(ctx) -commonLogger.Info("info") -``` - diff --git a/versioned_docs/version-v3.x/api/redirect.md b/versioned_docs/version-v3.x/api/redirect.md deleted file mode 100644 index e1403b73af9..00000000000 --- a/versioned_docs/version-v3.x/api/redirect.md +++ /dev/null @@ -1,264 +0,0 @@ ---- -id: redirect -title: πŸ”„ Redirect -description: Fiber's built-in redirect package -sidebar_position: 5 -toc_max_heading_level: 5 ---- - -Is used to redirect the ctx(request) to a different URL/Route. - -## Redirect Methods - -### To - -Redirects to the URL derived from the specified path, with specified [status](#status), a positive integer that -corresponds to an HTTP status code. - -:::info -If **not** specified, status defaults to **302 Found**. -::: - -```go title="Signature" -func (r *Redirect) To(location string) error -``` - -```go title="Example" -app.Get("/coffee", func(c fiber.Ctx) error { - // => HTTP - GET 301 /teapot - return c.Redirect().Status(fiber.StatusMovedPermanently).To("/teapot") -}) - -app.Get("/teapot", func(c fiber.Ctx) error { - return c.Status(fiber.StatusTeapot).Send("🍡 short and stout 🍡") -}) -``` - -```go title="More examples" -app.Get("/", func(c fiber.Ctx) error { - // => HTTP - GET 302 /foo/bar - return c.Redirect().To("/foo/bar") - // => HTTP - GET 302 ../login - return c.Redirect().To("../login") - // => HTTP - GET 302 http://example.com - return c.Redirect().To("http://example.com") - // => HTTP - GET 301 https://example.com - return c.Redirect().Status(301).To("http://example.com") -}) -``` - -### Route - -Redirects to the specific route along with the parameters and queries. - -:::info -If you want to send queries and params to route, you must use the [**RedirectConfig**](#redirectconfig) struct. -::: - -```go title="Signature" -func (r *Redirect) Route(name string, config ...RedirectConfig) error -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - // /user/fiber - return c.Redirect().Route("user", fiber.RedirectConfig{ - Params: fiber.Map{ - "name": "fiber", - }, - }) -}) - -app.Get("/with-queries", func(c fiber.Ctx) error { - // /user/fiber?data[0][name]=john&data[0][age]=10&test=doe - return c.Route("user", RedirectConfig{ - Params: fiber.Map{ - "name": "fiber", - }, - Queries: map[string]string{ - "data[0][name]": "john", - "data[0][age]": "10", - "test": "doe", - }, - }) -}) - -app.Get("/user/:name", func(c fiber.Ctx) error { - return c.SendString(c.Params("name")) -}).Name("user") -``` - -### Back - -Redirects back to refer URL. It redirects to fallback URL if refer header doesn't exists, with specified status, a -positive integer that corresponds to an HTTP status code. - -:::info -If **not** specified, status defaults to **302 Found**. -::: - -```go title="Signature" -func (r *Redirect) Back(fallback string) error -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Home page") -}) -app.Get("/test", func(c fiber.Ctx) error { - c.Set("Content-Type", "text/html") - return c.SendString(`Back`) -}) - -app.Get("/back", func(c fiber.Ctx) error { - return c.Redirect().Back("/") -}) -``` - -## Controls - -:::info -Method are **chainable**. -::: - -### Status - -Sets the HTTP status code for the redirect. - -:::info -Is used in conjunction with [**To**](#to), [**Route**](#route) and [**Back**](#back) methods. -::: - -```go title="Signature" -func (r *Redirect) Status(status int) *Redirect -``` - -```go title="Example" -app.Get("/coffee", func(c fiber.Ctx) error { - // => HTTP - GET 301 /teapot - return c.Redirect().Status(fiber.StatusMovedPermanently).To("/teapot") -}) -``` - -### RedirectConfig - -Sets the configuration for the redirect. - -:::info -Is used in conjunction with the [**Route**](#route) method. -::: - -```go -// RedirectConfig A config to use with Redirect().Route() -type RedirectConfig struct { - Params fiber.Map // Route parameters - Queries map[string]string // Query map -} -``` - -### Flash Message - -Similar to [Laravel](https://laravel.com/docs/11.x/redirects#redirecting-with-flashed-session-data) we can flash a message and retrieve it in the next request. - -#### Messages - -Get flash messages. Check [With](#with) for more information. - -```go title="Signature" -func (r *Redirect) Messages() map[string]string -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - messages := c.Redirect().Messages() - return c.JSON(messages) -}) -``` - -#### Message - -Get flash message by key. Check [With](#with) for more information. - -```go title="Signature" -func (r *Redirect) Message(key string) *Redirect -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - message := c.Redirect().Message("status") - return c.SendString(message) -}) -``` - - -#### OldInputs - -Get old input data. Check [WithInput](#withinput) for more information. - -```go title="Signature" -func (r *Redirect) OldInputs() map[string]string -``` - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - oldInputs := c.Redirect().OldInputs() - return c.JSON(oldInputs) -}) -``` - -#### OldInput - -Get old input data by key. Check [WithInput](#withinput) for more information. - -```go title="Signature" -func (r *Redirect) OldInput(key string) string -``` - -```go title="Example" -app.Get("/name", func(c fiber.Ctx) error { - oldInput := c.Redirect().OldInput("name") - return c.SendString(oldInput) -}) -``` - -#### With - -You can send flash messages by using `With()`. - -```go title="Signature" -func (r *Redirect) With(key, value string) *Redirect -``` - -```go title="Example" -app.Get("/login", func(c fiber.Ctx) error { - return c.Redirect().With("status", "Logged in successfully").To("/") -}) - -app.Get("/", func(c fiber.Ctx) error { - // => Logged in successfully - return c.SendString(c.Redirect().Message("status")) -}) -``` - -#### WithInput - -You can send input data by using `WithInput()`. -They will be sent as a cookie. - -This method can send form, multipart form, query data to redirected route depending on the request content type. - -```go title="Signature" -func (r *Redirect) WithInput() *Redirect -``` - -```go title="Example" -// curl -X POST http://localhost:3000/login -d "name=John" -app.Post("/login", func(c fiber.Ctx) error { - return c.Redirect().WithInput().Route("name") -}) - -app.Get("/name", func(c fiber.Ctx) error { - // => John - return c.SendString(c.Redirect().OldInput("name")) -}).Name("name") -``` diff --git a/versioned_docs/version-v3.x/client/_category_.json b/versioned_docs/version-v3.x/client/_category_.json deleted file mode 100644 index 61fad7ac4e4..00000000000 --- a/versioned_docs/version-v3.x/client/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "\uD83C\uDF0E Client", - "position": 5, - "link": { - "type": "generated-index", - "description": "HTTP client for Fiber." - } -} diff --git a/versioned_docs/version-v3.x/client/examples.md b/versioned_docs/version-v3.x/client/examples.md deleted file mode 100644 index 2ea79609da7..00000000000 --- a/versioned_docs/version-v3.x/client/examples.md +++ /dev/null @@ -1,250 +0,0 @@ ---- -id: examples -title: 🍳 Examples -description: >- - Client usage examples. -sidebar_position: 5 ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -## Basic Auth - - - - -```go -package main - -import ( - "encoding/base64" - "fmt" - - "github.com/gofiber/fiber/v3/client" -) - -func main() { - cc := client.New() - - out := base64.StdEncoding.EncodeToString([]byte("john:doe")) - resp, err := cc.Get("http://localhost:3000", client.Config{ - Header: map[string]string{ - "Authorization": "Basic " + out, - }, - }) - if err != nil { - panic(err) - } - - fmt.Print(string(resp.Body())) -} -``` - - - -```go -package main - -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/basicauth" -) - -func main() { - app := fiber.New() - app.Use( - basicauth.New(basicauth.Config{ - Users: map[string]string{ - "john": "doe", - }, - }), - ) - - app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") - }) - - app.Listen(":3000") -} -``` - - - -## TLS - - - - -```go -package main - -import ( - "crypto/tls" - "crypto/x509" - "fmt" - "os" - - "github.com/gofiber/fiber/v3/client" -) - -func main() { - cc := client.New() - - certPool, err := x509.SystemCertPool() - if err != nil { - panic(err) - } - - cert, err := os.ReadFile("ssl.cert") - if err != nil { - panic(err) - } - - certPool.AppendCertsFromPEM(cert) - cc.SetTLSConfig(&tls.Config{ - RootCAs: certPool, - }) - - resp, err := cc.Get("https://localhost:3000") - if err != nil { - panic(err) - } - - fmt.Print(string(resp.Body())) -} -``` - - - -```go -package main - -import ( - "github.com/gofiber/fiber/v3" -) - -func main() { - app := fiber.New() - - app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") - }) - - err := app.Listen(":3000", fiber.ListenConfig{ - CertFile: "ssl.cert", - CertKeyFile: "ssl.key", - }) - if err != nil { - panic(err) - } -} -``` - - - -## Cookiejar - -### Request - -```go -func main() { - jar := client.AcquireCookieJar() - defer client.ReleaseCookieJar(jar) - - cc := client.New() - cc.SetCookieJar(jar) - - jar.SetKeyValueBytes("httpbin.org", []byte("john"), []byte("doe")) - - resp, err := cc.Get("https://httpbin.org/cookies") - if err != nil { - panic(err) - } - - fmt.Println(string(resp.Body())) -} -``` - -
-Click here to see the result - -```json -{ - "cookies": { - "john": "doe" - } -} -``` - -
- -### Response - -```go -func main() { - jar := client.AcquireCookieJar() - defer client.ReleaseCookieJar(jar) - - cc := client.New() - cc.SetCookieJar(jar) - - _, err := cc.Get("https://httpbin.org/cookies/set/john/doe") - if err != nil { - panic(err) - } - - uri := fasthttp.AcquireURI() - defer fasthttp.ReleaseURI(uri) - - uri.SetHost("httpbin.org") - uri.SetPath("/cookies") - fmt.Println(jar.Get(uri)) -} -``` - -
-Click here to see the result - -```plaintext -[john=doe; path=/] -``` - -
- -### Response 2 - -```go -func main() { - jar := client.AcquireCookieJar() - defer client.ReleaseCookieJar(jar) - - cc := client.New() - cc.SetCookieJar(jar) - - _, err := cc.Get("https://httpbin.org/cookies/set/john/doe") - if err != nil { - panic(err) - } - - resp, err := cc.Get("https://httpbin.org/cookies") - if err != nil { - panic(err) - } - - fmt.Println(resp.String()) -} -``` - -
-Click here to see the result - -```json -{ - "cookies": { - "john": "doe" - } -} -``` - -
diff --git a/versioned_docs/version-v3.x/client/hooks.md b/versioned_docs/version-v3.x/client/hooks.md deleted file mode 100644 index 3ae510f3543..00000000000 --- a/versioned_docs/version-v3.x/client/hooks.md +++ /dev/null @@ -1,261 +0,0 @@ ---- -id: hooks -title: 🎣 Hooks -description: >- - Hooks are used to manipulate request/response proccess of Fiber client. -sidebar_position: 4 ---- - -With hooks, you can manipulate the client on before request/after response stages or more complex logging/tracing cases. - -There are 2 kinds of hooks: - -## Request Hooks - -They are called before the HTTP request has been sent. You can use them make changes on Request object. - -You need to use `RequestHook func(*Client, *Request) error` function signature while creating the hooks. You can use request hooks to change host URL, log request properties etc. Here is an example about how to create request hooks: - -```go -type Repository struct { - Name string `json:"name"` - FullName string `json:"full_name"` - Description string `json:"description"` - Homepage string `json:"homepage"` - - Owner struct { - Login string `json:"login"` - } `json:"owner"` -} - -func main() { - cc := client.New() - - cc.AddRequestHook(func(c *client.Client, r *client.Request) error { - r.SetURL("https://api.github.com/" + r.URL()) - - return nil - }) - - resp, err := cc.Get("repos/gofiber/fiber") - if err != nil { - panic(err) - } - - var repo Repository - if err := resp.JSON(&repo); err != nil { - panic(err) - } - - fmt.Printf("Status code: %d\n", resp.StatusCode()) - - fmt.Printf("Repository: %s\n", repo.FullName) - fmt.Printf("Description: %s\n", repo.Description) - fmt.Printf("Homepage: %s\n", repo.Homepage) - fmt.Printf("Owner: %s\n", repo.Owner.Login) - fmt.Printf("Name: %s\n", repo.Name) - fmt.Printf("Full Name: %s\n", repo.FullName) -} -``` - -
-Click here to see the result - -```plaintext -Status code: 200 -Repository: gofiber/fiber -Description: ⚑️ Express inspired web framework written in Go -Homepage: https://gofiber.io -Owner: gofiber -Name: fiber -Full Name: gofiber/fiber -``` - -
- -There are also some builtin request hooks provide some functionalities for Fiber client. Here is a list of them: - -- [parserRequestURL](https://github.com/gofiber/fiber/blob/main/client/hooks.go#L62): parserRequestURL customizes the URL according to the path params and query params. It's necessary for `PathParam` and `QueryParam` methods. - -- [parserRequestHeader](https://github.com/gofiber/fiber/blob/main/client/hooks.go#L113): parserRequestHeader sets request headers, cookies, body type, referer, user agent according to client and request proeprties. It's necessary to make request header and cookiejar methods functional. - -- [parserRequestBody](https://github.com/gofiber/fiber/blob/main/client/hooks.go#L178): parserRequestBody serializes the body automatically. It is useful for XML, JSON, form, file bodies. - -:::info -If any error returns from request hook execution, it will interrupt the request and return the error. -::: - -```go -func main() { - cc := client.New() - - cc.AddRequestHook(func(c *client.Client, r *client.Request) error { - fmt.Println("Hook 1") - return errors.New("error") - }) - - cc.AddRequestHook(func(c *client.Client, r *client.Request) error { - fmt.Println("Hook 2") - return nil - }) - - _, err := cc.Get("https://example.com/") - if err != nil { - panic(err) - } -} -``` - -
-Click here to see the result - -```shell -Hook 1. -panic: error - -goroutine 1 [running]: -main.main() - main.go:25 +0xaa -exit status 2 -``` - -
- -## Response Hooks - -They are called after the HTTP response has been completed. You can use them to get some information about response and request. - -You need to use `ResponseHook func(*Client, *Response, *Request) error` function signature while creating the hooks. You can use response hook for logging, tracing etc. Here is an example about how to create response hooks: - -```go -func main() { - cc := client.New() - - cc.AddResponseHook(func(c *client.Client, resp *client.Response, req *client.Request) error { - fmt.Printf("Response Status Code: %d\n", resp.StatusCode()) - fmt.Printf("HTTP protocol: %s\n\n", resp.Protocol()) - - fmt.Println("Response Headers:") - resp.RawResponse.Header.VisitAll(func(key, value []byte) { - fmt.Printf("%s: %s\n", key, value) - }) - - return nil - }) - - _, err := cc.Get("https://example.com/") - if err != nil { - panic(err) - } -} -``` - -
-Click here to see the result - -```plaintext -Response Status Code: 200 -HTTP protocol: HTTP/1.1 - -Response Headers: -Content-Length: 1256 -Content-Type: text/html; charset=UTF-8 -Server: ECAcc (dcd/7D5A) -Age: 216114 -Cache-Control: max-age=604800 -Date: Fri, 10 May 2024 10:49:10 GMT -Etag: "3147526947+gzip+ident" -Expires: Fri, 17 May 2024 10:49:10 GMT -Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT -Vary: Accept-Encoding -X-Cache: HIT -``` - -
- -There are also some builtin request hooks provide some functionalities for Fiber client. Here is a list of them: - -- [parserResponseCookie](https://github.com/gofiber/fiber/blob/main/client/hooks.go#L293): parserResponseCookie parses cookies and saves into the response objects and cookiejar if it's exists. - -- [logger](https://github.com/gofiber/fiber/blob/main/client/hooks.go#L319): logger prints some RawRequest and RawResponse information. It uses [log.CommonLogger](https://github.com/gofiber/fiber/blob/main/log/log.go#L49) interface for logging. - -:::info -If any error is returned from executing the response hook, it will return the error without executing other response hooks. -::: - -```go -func main() { - cc := client.New() - - cc.AddResponseHook(func(c *client.Client, r1 *client.Response, r2 *client.Request) error { - fmt.Println("Hook 1") - return nil - }) - - cc.AddResponseHook(func(c *client.Client, r1 *client.Response, r2 *client.Request) error { - fmt.Println("Hook 2") - return errors.New("error") - }) - - cc.AddResponseHook(func(c *client.Client, r1 *client.Response, r2 *client.Request) error { - fmt.Println("Hook 3") - return nil - }) - - _, err := cc.Get("https://example.com/") - if err != nil { - panic(err) - } -} -``` - -
-Click here to see the result - -```shell -Hook 1 -Hook 2 -panic: error - -goroutine 1 [running]: -main.main() - main.go:30 +0xd6 -exit status 2 -``` - -
- -:::info -Hooks work as FIFO (first-in-first-out). You need to check the order while adding the hooks. -::: - -```go -func main() { - cc := client.New() - - cc.AddRequestHook(func(c *client.Client, r *client.Request) error { - fmt.Println("Hook 1") - return nil - }) - - cc.AddRequestHook(func(c *client.Client, r *client.Request) error { - fmt.Println("Hook 2") - return nil - }) - - _, err := cc.Get("https://example.com/") - if err != nil { - panic(err) - } -} -``` - -
-Click here to see the result - -```plaintext -Hook 1 -Hook 2 -``` - -
diff --git a/versioned_docs/version-v3.x/client/request.md b/versioned_docs/version-v3.x/client/request.md deleted file mode 100644 index a5a025bdada..00000000000 --- a/versioned_docs/version-v3.x/client/request.md +++ /dev/null @@ -1,1364 +0,0 @@ ---- -id: request -title: πŸ“€ Request -description: >- - Request methods of Gofiber HTTP client. -sidebar_position: 2 ---- - -The `Request` structure in Gofiber's HTTP client represents an HTTP request. It encapsulates all the necessary information required to send a request to a server. This includes: - -- **URL**: The URL to which the request is sent. -- **Method**: The HTTP method used (GET, POST, PUT, DELETE, etc.). -- **Headers**: HTTP headers that provide additional information about the request or the needed responses. -- **Body**: The data sent with the request, typically used with POST and PUT methods. -- **Query Parameters**: Parameters that are appended to the URL, used to modify the request or to provide additional information. - -This structure is designed to be flexible and efficient, allowing users to easily construct and modify HTTP requests according to their needs. - -```go -type Request struct { - url string - method string - userAgent string - boundary string - referer string - ctx context.Context - header *Header - params *QueryParam - cookies *Cookie - path *PathParam - - timeout time.Duration - maxRedirects int - - client *Client - - body any - formData *FormData - files []*File - bodyType bodyType - - RawRequest *fasthttp.Request -} -``` - - -## REST Methods - -### Get - -Get sends the GET request. -It sets the URL and HTTP method, and then it sends the request. - -```go title="Signature" -func (r *Request) Get(url string) (*Response, error) -``` - -### Post - -Post sends the POST request. -It sets the URL and HTTP method, and then it sends the request. - -```go title="Signature" -func (r *Request) Post(url string) (*Response, error) -``` - -### Put - -Put sends the PUT request. -It sets the URL and HTTP method, and then it sends the request. - -```go title="Signature" -func (r *Request) Put(url string) (*Response, error) -``` - -### Patch - -Patch sends the PATCH request. -It sets the URL and HTTP method, and then it sends the request. - -```go title="Signature" -func (r *Request) Patch(url string) (*Response, error) -``` - -### Delete - -Delete sends the DELETE request. -It sets the URL and HTTP method, and then it sends the request. - -```go title="Signature" -func (r *Request) Delete(url string) (*Response, error) -``` - -### Head - -Head sends the HEAD request. -It sets the URL and HTTP method, and then it sends the request. - -```go title="Signature" -func (r *Request) Head(url string) (*Response, error) -``` - -### Options - -Options sends the OPTIONS request. -It sets the URL and HTTP method, and then it sends the request. - -```go title="Signature" -func (r *Request) Options(url string) (*Response, error) -``` - -### Custom - -Custom sends a request with custom HTTP method. -It sets the URL and HTTP method, and then it sends the request. -You can use Custom to send requests with methods like TRACE, CONNECT. - -```go title="Signature" -func (r *Request) Custom(url, method string) (*Response, error) -``` - -## AcquireRequest - -AcquireRequest returns an empty request object from the pool. -The returned request may be returned to the pool with ReleaseRequest when no longer needed. -This allows reducing GC load. - -```go title="Signature" -func AcquireRequest() *Request -``` - -## ReleaseRequest - -ReleaseRequest returns the object acquired via AcquireRequest to the pool. -Do not access the released Request object; otherwise, data races may occur. - -```go title="Signature" -func ReleaseRequest(req *Request) -``` - -## Method - -Method returns HTTP method in request. - -```go title="Signature" -func (r *Request) Method() string -``` - -## SetMethod - -SetMethod will set method for Request object. The user should use request method to set method. - -```go title="Signature" -func (r *Request) SetMethod(method string) *Request -``` - -## URL - -URL returns request url in Request instance. - -```go title="Signature" -func (r *Request) URL() string -``` - -## SetURL - -SetURL will set url for Request object. - -```go title="Signature" -func (r *Request) SetURL(url string) *Request -``` - -## Client - -Client gets the Client instance of Request. - -```go title="Signature" -func (r *Request) Client() *Client -``` - -## SetClient - -SetClient method sets client of request instance. -If the client given is null, it will panic. - -```go title="Signature" -func (r *Request) SetClient(c *Client) *Request -``` - -## Context - -Context returns the Context if it's already set in the request; otherwise, it returns `context.Background()`. - -```go title="Signature" -func (r *Request) Context() context.Context -``` - -## SetContext - -SetContext sets the context.Context for current Request. It allows interruption of the request execution if the ctx.Done() channel is closed. -See [the article](https://blog.golang.org/context) and the [context](https://pkg.go.dev/context) package documentation. - -```go title="Signature" -func (r *Request) SetContext(ctx context.Context) *Request -``` - -## Header - -Header method returns header value via key, this method will visit all field in the header. -```go title="Signature" -func (r *Request) Header(key string) []string -``` - -### AddHeader - -AddHeader method adds a single header field and its value in the request instance. - -```go title="Signature" -func (r *Request) AddHeader(key, val string) *Request -``` - -```go title="Example" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.AddHeader("Golang", "Fiber") -req.AddHeader("Test", "123456") -req.AddHeader("Test", "654321") - -resp, err := req.Get("https://httpbin.org/headers") -if err != nil { - panic(err) -} - -fmt.Println(resp.String()) -``` - -
-Click here to see the result - -```json -{ - "headers": { - "Golang": "Fiber", - "Host": "httpbin.org", - "Referer": "", - "Test": "123456,654321", - "User-Agent": "fiber", - "X-Amzn-Trace-Id": "Root=1-664105d2-033cf7173457adb56d9e7193" - } -} -``` - -
- -### SetHeader - -SetHeader method sets a single header field and its value in the request instance. -It will override the header which has been set in the client instance. - -```go title="Signature" -func (r *Request) SetHeader(key, val string) *Request -``` - -```go title="Example" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.SetHeader("Test", "123456") -req.SetHeader("Test", "654321") - -resp, err := req.Get("https://httpbin.org/headers") -if err != nil { - panic(err) -} - -fmt.Println(resp.String()) -``` - -
-Click here to see the result - -```json -{ - "headers": { - "Golang": "Fiber", - "Host": "httpbin.org", - "Referer": "", - "Test": "654321", - "User-Agent": "fiber", - "X-Amzn-Trace-Id": "Root=1-664105e5-5d676ba348450cdb62847f04" - } -} -``` - -
- -### AddHeaders - -AddHeaders method adds multiple header fields and its values at one go in the request instance. - -```go title="Signature" -func (r *Request) AddHeaders(h map[string][]string) *Request -``` - -### SetHeaders - -SetHeaders method sets multiple header fields and its values at one go in the request instance. -It will override the header which has been set in the client instance. - -```go title="Signature" -func (r *Request) SetHeaders(h map[string]string) *Request -``` - -## Param - -Param method returns params value via key, this method will visit all field in the query param. - -```go title="Signature" -func (r *Request) Param(key string) []string -``` - -### AddParam - -AddParam method adds a single param field and its value in the request instance. - -```go title="Signature" -func (r *Request) AddParam(key, val string) *Request -``` - -```go title="Example" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.AddParam("name", "john") -req.AddParam("hobbies", "football") -req.AddParam("hobbies", "basketball") - -resp, err := req.Get("https://httpbin.org/response-headers") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -```json -{ - "Content-Length": "145", - "Content-Type": "application/json", - "hobbies": [ - "football", - "basketball" - ], - "name": "efectn" -} -``` - -
- -### SetParam - -SetParam method sets a single param field and its value in the request instance. -It will override param, which has been set in client instance. - -```go title="Signature" -func (r *Request) SetParam(key, val string) *Request -``` - -### AddParams - -AddParams method adds multiple param fields and its values at one go in the request instance. - -```go title="Signature" -func (r *Request) AddParams(m map[string][]string) *Request -``` - -### SetParams - -SetParams method sets multiple param fields and its values at one go in the request instance. -It will override param, which has been set in client instance. - -```go title="Signature" -func (r *Request) SetParams(m map[string]string) *Request -``` - -### SetParamsWithStruct - -SetParamsWithStruct method sets multiple param fields and its values at one go in the request instance. -It will override param, which has been set in client instance. - -```go title="Signature" -func (r *Request) SetParamsWithStruct(v any) *Request -``` - -```go title="Example" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.SetParamsWithStruct(struct { - Name string `json:"name"` - Hobbies []string `json:"hobbies"` -}{ - Name: "John Doe", - Hobbies: []string{ - "Football", - "Basketball", - }, -}) - -resp, err := req.Get("https://httpbin.org/response-headers") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -```json -{ - "Content-Length": "147", - "Content-Type": "application/json", - "Hobbies": [ - "Football", - "Basketball" - ], - "Name": "John Doe" -} -``` - -
- -### DelParams - -DelParams method deletes single or multiple param fields and their values. - -```go title="Signature" -func (r *Request) DelParams(key ...string) *Request -``` - -## UserAgent - -UserAgent returns user agent in request instance. - -```go title="Signature" -func (r *Request) UserAgent() string -``` - -## SetUserAgent - -SetUserAgent method sets user agent in request. -It will override the user agent which has been set in the client instance. - -```go title="Signature" -func (r *Request) SetUserAgent(ua string) *Request -``` - -## Boundary - -Boundary returns boundary in multipart boundary. - -```go title="Signature" -func (r *Request) Boundary() string -``` - -## SetBoundary - -SetBoundary method sets multipart boundary. - -```go title="Signature" -func (r *Request) SetBoundary(b string) *Request -``` - -## Referer - -Referer returns referer in request instance. - -```go title="Signature" -func (r *Request) Referer() string -``` - -## SetReferer - -SetReferer method sets referer in request. -It will override referer which set in client instance. - -```go title="Signature" -func (r *Request) SetReferer(referer string) *Request -``` - -## Cookie - -Cookie returns the cookie set in the request instance. If the cookie doesn't exist, returns empty string. - -```go title="Signature" -func (r *Request) Cookie(key string) string -``` - -### SetCookie - -SetCookie method sets a single cookie field and its value in the request instance. -It will override the cookie which is set in the client instance. - -```go title="Signature" -func (r *Request) SetCookie(key, val string) *Request -``` - -### SetCookies - -SetCookies method sets multiple cookie fields and its values at one go in the request instance. -It will override the cookie which is set in the client instance. - -```go title="Signature" -func (r *Request) SetCookies(m map[string]string) *Request -``` - -```go title="Example" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.SetCookies(map[string]string{ - "cookie1": "value1", - "cookie2": "value2", -}) - -resp, err := req.Get("https://httpbin.org/cookies") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -```json -{ - "cookies": { - "test": "123" - } -} -``` - -
- -### SetCookiesWithStruct - -SetCookiesWithStruct method sets multiple cookie fields and its values at one go in the request instance. -It will override the cookie which is set in the client instance. - -```go title="Signature" -func (r *Request) SetCookiesWithStruct(v any) *Request -``` - -### DelCookies - -DelCookies method deletes single or multiple cookie fields ant its values. - -```go title="Signature" -func (r *Request) DelCookies(key ...string) *Request -``` - -## PathParam - -PathParam returns the path param set in the request instance. If the path param doesn't exist, return empty string. - -```go title="Signature" -func (r *Request) PathParam(key string) string -``` - -### SetPathParam - -SetPathParam method sets a single path param field and its value in the request instance. -It will override path param which set in client instance. - -```go title="Signature" -func (r *Request) SetPathParam(key, val string) *Request -``` - -```go title="Example" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.SetPathParam("base64", "R29maWJlcg==") - -resp, err := req.Get("https://httpbin.org/base64/:base64") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -```plaintext -Gofiber -``` - -
- -### SetPathParams - -SetPathParams method sets multiple path param fields and its values at one go in the request instance. -It will override path param which set in client instance. - -```go title="Signature" -func (r *Request) SetPathParams(m map[string]string) *Request -``` - -### SetPathParamsWithStruct - -SetPathParamsWithStruct method sets multiple path param fields and its values at one go in the request instance. -It will override path param which set in client instance. - -```go title="Signature" -func (r *Request) SetPathParamsWithStruct(v any) *Request -``` - -### DelPathParams - -DelPathParams method deletes single or multiple path param fields ant its values. - -```go title="Signature" -func (r *Request) DelPathParams(key ...string) *Request -``` - -### ResetPathParams - -ResetPathParams deletes all path params. - -```go title="Signature" -func (r *Request) ResetPathParams() *Request -``` - -## SetJSON - -SetJSON method sets JSON body in request. - -```go title="Signature" -func (r *Request) SetJSON(v any) *Request -``` - -## SetXML - -SetXML method sets XML body in request. - -```go title="Signature" -func (r *Request) SetXML(v any) *Request -``` - -## SetRawBody - -SetRawBody method sets body with raw data in request. - -```go title="Signature" -func (r *Request) SetRawBody(v []byte) *Request -``` - -## FormData - -FormData method returns form data value via key, this method will visit all field in the form data. - -```go title="Signature" -func (r *Request) FormData(key string) []string -``` - -### AddFormData - -AddFormData method adds a single form data field and its value in the request instance. - -```go title="Signature" -func (r *Request) AddFormData(key, val string) *Request -``` - -```go title="Example" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.AddFormData("points", "80") -req.AddFormData("points", "90") -req.AddFormData("points", "100") - -resp, err := req.Post("https://httpbin.org/post") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -```json -{ - "args": {}, - "data": "", - "files": {}, - "form": { - "points": [ - "80", - "90", - "100" - ] - }, - // ... -} -``` - -
- -### SetFormData - -SetFormData method sets a single form data field and its value in the request instance. - -```go title="Signature" -func (r *Request) SetFormData(key, val string) *Request -``` - -```go title="Example" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.SetFormData("name", "john") -req.SetFormData("email", "john@doe.com") - -resp, err := req.Post("https://httpbin.org/post") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -```json -{ - "args": {}, - "data": "", - "files": {}, - "form": { - "email": "john@doe.com", - "name": "john" - }, - // ... -} -``` - -
- -### AddFormDatas - -AddFormDatas method adds multiple form data fields and its values in the request instance. - -```go title="Signature" -func (r *Request) AddFormDatas(m map[string][]string) *Request -``` - -### SetFormDatas - -SetFormDatas method sets multiple form data fields and its values in the request instance. - -```go title="Signature" -func (r *Request) SetFormDatas(m map[string]string) *Request -``` - -### SetFormDatas - -SetFormDatas method sets multiple form data fields and its values in the request instance. - -```go title="Signature" -func (r *Request) SetFormDatas(m map[string]string) *Request -``` - -### SetFormDatasWithStruct - -SetFormDatasWithStruct method sets multiple form data fields and its values in the request instance via struct. - -```go title="Signature" -func (r *Request) SetFormDatasWithStruct(v any) *Request -``` - -### DelFormDatas - -DelFormDatas method deletes multiple form data fields and its value in the request instance. - -```go title="Signature" -func (r *Request) DelFormDatas(key ...string) *Request -``` - -## File - -File returns file ptr store in request obj by name. -If the name field is empty, it will try to match path. - -```go title="Signature" -func (r *Request) File(name string) *File -``` - -### FileByPath - -FileByPath returns file ptr store in request obj by path. - -```go title="Signature" -func (r *Request) FileByPath(path string) *File -``` - -### AddFile - -AddFile method adds a single file field and its value in the request instance via file path. - -```go title="Signature" -func (r *Request) AddFile(path string) *Request -``` - -```go title="Example" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.AddFile("test.txt") - -resp, err := req.Post("https://httpbin.org/post") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -```json -{ - "args": {}, - "data": "", - "files": { - "file1": "This is an empty file!\n" - }, - "form": {}, - // ... -} -``` - -
- -### AddFileWithReader - -AddFileWithReader method adds a single field and its value in the request instance via reader. - -```go title="Signature" -func (r *Request) AddFileWithReader(name string, reader io.ReadCloser) *Request -``` - -```go title="Example" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -buf := bytes.NewBuffer([]byte("Hello, World!")) -req.AddFileWithReader("test.txt", io.NopCloser(buf)) - -resp, err := req.Post("https://httpbin.org/post") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -```json -{ - "args": {}, - "data": "", - "files": { - "file1": "Hello, World!" - }, - "form": {}, - // ... -} -``` - -
- -### AddFiles - -AddFiles method adds multiple file fields and its value in the request instance via File instance. - -```go title="Signature" -func (r *Request) AddFiles(files ...*File) *Request -``` - -## Timeout - -Timeout returns the length of timeout in request. - -```go title="Signature" -func (r *Request) Timeout() time.Duration -``` - -## SetTimeout - -SetTimeout method sets the timeout field and its values at one go in the request instance. -It will override timeout which set in client instance. - -```go title="Signature" -func (r *Request) SetTimeout(t time.Duration) *Request -``` - -```go title="Example 1" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.SetTimeout(5 * time.Second) - -resp, err := req.Get("https://httpbin.org/delay/4") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -```json -{ - "args": {}, - "data": "", - "files": {}, - "form": {}, - // ... -} -``` - -
- -```go title="Example 2" -req := client.AcquireRequest() -defer client.ReleaseRequest(req) - -req.SetTimeout(5 * time.Second) - -resp, err := req.Get("https://httpbin.org/delay/6") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -```shell -panic: timeout or cancel - -goroutine 1 [running]: -main.main() - main.go:18 +0xeb -exit status 2 -``` - -
- -## MaxRedirects - -MaxRedirects returns the max redirects count in the request. - -```go title="Signature" -func (r *Request) MaxRedirects() int -``` - -## SetMaxRedirects - -SetMaxRedirects method sets the maximum number of redirects at one go in the request instance. -It will override max redirect, which is set in the client instance. - -```go title="Signature" -func (r *Request) SetMaxRedirects(count int) *Request -``` - -## Send - -Send sends HTTP request. - -```go title="Signature" -func (r *Request) Send() (*Response, error) -``` - -## Reset - -Reset clears Request object, used by ReleaseRequest method. - -```go title="Signature" -func (r *Request) Reset() -``` - -## Header - -Header is a wrapper which wrap http.Header, the header in client and request will store in it. - -```go -type Header struct { - *fasthttp.RequestHeader -} -``` - -### PeekMultiple - -PeekMultiple methods returns multiple field in header with same key. - -```go title="Signature" -func (h *Header) PeekMultiple(key string) []string -``` - -### AddHeaders - -AddHeaders receives a map and add each value to header. - -```go title="Signature" -func (h *Header) AddHeaders(r map[string][]string) -``` - -### SetHeaders - -SetHeaders will override all headers. - -```go title="Signature" -func (h *Header) SetHeaders(r map[string]string) -``` - -## QueryParam - -QueryParam is a wrapper which wrap url.Values, the query string and formdata in client and request will store in it. - -```go -type QueryParam struct { - *fasthttp.Args -} -``` - -### AddParams - -AddParams receive a map and add each value to param. - -```go title="Signature" -func (p *QueryParam) AddParams(r map[string][]string) -``` - -### SetParams - -SetParams will override all params. - -```go title="Signature" -func (p *QueryParam) SetParams(r map[string]string) -``` - -### SetParamsWithStruct - -SetParamsWithStruct will override all params with struct or pointer of struct. -Nested structs are not currently supported. - -```go title="Signature" -func (p *QueryParam) SetParamsWithStruct(v any) -``` - -## Cookie - -Cookie is a map which to store the cookies. - -```go -type Cookie map[string]string -``` - -### Add - -Add method impl the method in WithStruct interface. - -```go title="Signature" -func (c Cookie) Add(key, val string) -``` - -### Del - -Del method impl the method in WithStruct interface. - -```go title="Signature" -func (c Cookie) Del(key string) -``` - -### SetCookie - -SetCookie method sets a single val in Cookie. - -```go title="Signature" -func (c Cookie) SetCookie(key, val string) -``` - -### SetCookies - -SetCookies method sets multiple val in Cookie. - -```go title="Signature" -func (c Cookie) SetCookies(m map[string]string) -``` - -### SetCookiesWithStruct - -SetCookiesWithStruct method sets multiple val in Cookie via a struct. - -```go title="Signature" -func (c Cookie) SetCookiesWithStruct(v any) -``` - -### DelCookies - -DelCookies method deletes multiple val in Cookie. - -```go title="Signature" -func (c Cookie) DelCookies(key ...string) -``` - -### VisitAll - -VisitAll method receive a function which can travel the all val. - -```go title="Signature" -func (c Cookie) VisitAll(f func(key, val string)) -``` - -### Reset - -Reset clears the Cookie object. - -```go title="Signature" -func (c Cookie) Reset() -``` - -## PathParam - -PathParam is a map which to store path params. - -```go -type PathParam map[string]string -``` - -### Add - -Add method impl the method in WithStruct interface. - -```go title="Signature" -func (p PathParam) Add(key, val string) -``` - -### Del - -Del method impl the method in WithStruct interface. - -```go title="Signature" -func (p PathParam) Del(key string) -``` - -### SetParam - -SetParam method sets a single val in PathParam. - -```go title="Signature" -func (p PathParam) SetParam(key, val string) -``` - -### SetParams - -SetParams method sets multiple val in PathParam. - -```go title="Signature" -func (p PathParam) SetParams(m map[string]string) -``` - -### SetParamsWithStruct - -SetParamsWithStruct method sets multiple val in PathParam via a struct. - -```go title="Signature" -func (p PathParam) SetParamsWithStruct(v any) -``` - -### DelParams - -DelParams method deletes multiple val in PathParams. - -```go title="Signature" -func (p PathParam) DelParams(key ...string) -``` - -### VisitAll - -VisitAll method receive a function which can travel the all val. - -```go title="Signature" -func (p PathParam) VisitAll(f func(key, val string)) -``` - -### Reset - -Reset clears the PathParam object. - -```go title="Signature" -func (p PathParam) Reset() -``` - -## FormData - -FormData is a wrapper of fasthttp.Args and it is used for url encode body and file body. - -```go -type FormData struct { - *fasthttp.Args -} -``` - -### AddData - -AddData method is a wrapper of Args's Add method. - -```go title="Signature" -func (f *FormData) AddData(key, val string) -``` - -### SetData - -SetData method is a wrapper of Args's Set method. - -```go title="Signature" -func (f *FormData) SetData(key, val string) -``` - -### AddDatas - -AddDatas method supports add multiple fields. - -```go title="Signature" -func (f *FormData) AddDatas(m map[string][]string) -``` - -### SetDatas - -SetDatas method supports set multiple fields. - -```go title="Signature" -func (f *FormData) SetDatas(m map[string]string) -``` - -### SetDatasWithStruct - -SetDatasWithStruct method supports set multiple fields via a struct. - -```go title="Signature" -func (f *FormData) SetDatasWithStruct(v any) -``` - -### DelDatas - -DelDatas method deletes multiple fields. - -```go title="Signature" -func (f *FormData) DelDatas(key ...string) -``` - -### Reset - -Reset clear the FormData object. - -```go title="Signature" -func (f *FormData) Reset() -``` - -## File - -File is a struct which support send files via request. - -```go -type File struct { - name string - fieldName string - path string - reader io.ReadCloser -} -``` - -### AcquireFile - -AcquireFile returns a File object from the pool. -And you can set field in the File with SetFileFunc. - -The returned file may be returned to the pool with ReleaseFile when no longer needed. -This allows reducing GC load. - -```go title="Signature" -func AcquireFile(setter ...SetFileFunc) *File -``` - -### ReleaseFile - -ReleaseFile returns the object acquired via AcquireFile to the pool. -Do not access the released File object, otherwise data races may occur. - -```go title="Signature" -func ReleaseFile(f *File) -``` - -### SetName - -SetName method sets file name. - -```go title="Signature" -func (f *File) SetName(n string) -``` - -### SetFieldName - -SetFieldName method sets key of file in the body. - -```go title="Signature" -func (f *File) SetFieldName(n string) -``` - -### SetPath - -SetPath method set file path. - -```go title="Signature" -func (f *File) SetPath(p string) -``` - -### SetReader - -SetReader method can receive an io.ReadCloser which will be closed in parserBody hook. - -```go title="Signature" -func (f *File) SetReader(r io.ReadCloser) -``` - -### Reset - -Reset clear the File object. - -```go title="Signature" -func (f *File) Reset() -``` diff --git a/versioned_docs/version-v3.x/client/response.md b/versioned_docs/version-v3.x/client/response.md deleted file mode 100644 index 85ea79c4834..00000000000 --- a/versioned_docs/version-v3.x/client/response.md +++ /dev/null @@ -1,212 +0,0 @@ ---- -id: response -title: πŸ“₯ Response -description: >- - Response methods of Gofiber HTTP client. -sidebar_position: 3 ---- - -The `Response` structure in Gofiber's HTTP client represents the server's response to an HTTP request. It contains all the necessary information received from the server. This includes: - -- **Status Code**: The HTTP status code returned by the server (e.g., 200 OK, 404 Not Found). -- **Headers**: HTTP headers received from the server that provide additional information about the response. -- **Body**: The data received from the server, typically in the form of a JSON, XML, or plain text format. -- **Cookies**: Any cookies sent by the server along with the response. - -This structure allows users to easily access and manage the data returned by the server, facilitating efficient handling of HTTP responses. - -```go -type Response struct { - client *Client - request *Request - cookie []*fasthttp.Cookie - - RawResponse *fasthttp.Response -} -``` - -## AcquireResponse - -AcquireResponse returns an empty response object from the pool. -The returned response may be returned to the pool with ReleaseResponse when no longer needed. -This allows reducing GC load. - -```go title="Signature" -func AcquireResponse() *Response -``` - -## ReleaseResponse - -ReleaseResponse returns the object acquired via AcquireResponse to the pool. -Do not access the released Response object; otherwise, data races may occur. - -```go title="Signature" -func ReleaseResponse(resp *Response) -``` - -## Status - -Status method returns the HTTP status string for the executed request. - -```go title="Signature" -func (r *Response) Status() string -``` - -## StatusCode - -StatusCode method returns the HTTP status code for the executed request. - -```go title="Signature" -func (r *Response) StatusCode() int -``` - -## Protocol - -Protocol method returns the HTTP response protocol used for the request. - -```go title="Signature" -func (r *Response) Protocol() string -``` - -```go title="Example" -resp, err := client.Get("https://httpbin.org/get") -if err != nil { - panic(err) -} - -fmt.Println(resp.Protocol()) -``` - -
-Click here to see the result - -``` -HTTP/1.1 -``` - -
- -## Header - -Header method returns the response headers. - -```go title="Signature" -func (r *Response) Header(key string) string -``` - -## Cookies - -Cookies method to access all the response cookies. - -```go title="Signature" -func (r *Response) Cookies() []*fasthttp.Cookie -``` - -```go title="Example" -resp, err := client.Get("https://httpbin.org/cookies/set/go/fiber") -if err != nil { - panic(err) -} - -cookies := resp.Cookies() -for _, cookie := range cookies { - fmt.Printf("%s => %s\n", string(cookie.Key()), string(cookie.Value())) -} -``` - -
-Click here to see the result - -``` -go => fiber -``` - -
- -## Body - -Body method returns HTTP response as []byte array for the executed request. - -```go title="Signature" -func (r *Response) Body() []byte -``` - -## String - -String method returns the body of the server response as String. - -```go title="Signature" -func (r *Response) String() string -``` - -## JSON - -JSON method will unmarshal body to json. - -```go title="Signature" -func (r *Response) JSON(v any) error -``` - -```go title="Example" -type Body struct { - Slideshow struct { - Author string `json:"author"` - Date string `json:"date"` - Title string `json:"title"` - } `json:"slideshow"` -} -var out Body - -resp, err := client.Get("https://httpbin.org/json") -if err != nil { - panic(err) -} - -err = resp.JSON(&out) -if err != nil { - panic(err) -} - -fmt.Printf("%+v\n", out) -``` - -
-Click here to see the result - -``` -{Slideshow:{Author:Yours Truly Date:date of publication Title:Sample Slide Show}} -``` - -
- -## XML - -XML method will unmarshal body to xml. - -```go title="Signature" -func (r *Response) XML(v any) error -``` - -## Save - -Save method will save the body to a file or io.Writer. - -```go title="Signature" -func (r *Response) Save(v any) error -``` - -## Reset - -Reset clears the Response object. - -```go title="Signature" -func (r *Response) Reset() -``` - -## Close - -Close method will release the Request and Response objects; after calling Close, please do not use these objects. - -```go title="Signature" -func (r *Response) Close() -``` diff --git a/versioned_docs/version-v3.x/client/rest.md b/versioned_docs/version-v3.x/client/rest.md deleted file mode 100644 index 9b34b80f421..00000000000 --- a/versioned_docs/version-v3.x/client/rest.md +++ /dev/null @@ -1,810 +0,0 @@ ---- -id: rest -title: πŸ–₯️ REST -description: >- - HTTP client for Gofiber. -sidebar_position: 1 -toc_max_heading_level: 5 ---- - -The Fiber Client for Fiber v3 is a powerful HTTP client optimized for high performance and ease of use in server-side applications. Built on top of the robust FastHTTP library, it inherits FastHTTP's high-speed HTTP protocol implementation. The client is designed to make HTTP requests both internally within services or externally to other web services. - -## Features -- **Lightweight & Fast**: Leveraging the minimalistic design of FastHTTP, the Fiber Client is lightweight and extremely fast. -- **Flexible Configuration**: Configure client-level settings such as timeouts, headers, and more, which apply to all requests. Specific requests can further override or merge these settings. -- **Connection Pooling**: Manages a pool of persistent connections that reduce the overhead of repeatedly establishing connections. -- **Timeouts & Retries**: Supports setting request timeouts and retry mechanisms to handle transient failures. - -## Usage -To use the Fiber Client, instantiate it with the desired configuration. Here's a simple example: - -```go -package main - -import ( - "fmt" - "time" - - "github.com/gofiber/fiber/v3/client" -) - -func main() { - cc := client.New() - cc.SetTimeout(10 * time.Second) - - // Get request - resp, err := cc.Get("https://httpbin.org/get") - if err != nil { - panic(err) - } - - fmt.Printf("Status: %d\n", resp.StatusCode()) - fmt.Printf("Body: %s\n", string(resp.Body())) -} -``` - -You can check out [examples](examples.md) for more examples! - -```go -type Client struct { - mu sync.RWMutex - - fasthttp *fasthttp.Client - - baseURL string - userAgent string - referer string - header *Header - params *QueryParam - cookies *Cookie - path *PathParam - - debug bool - - timeout time.Duration - - // user defined request hooks - userRequestHooks []RequestHook - - // client package defined request hooks - builtinRequestHooks []RequestHook - - // user defined response hooks - userResponseHooks []ResponseHook - - // client package defined response hooks - builtinResponseHooks []ResponseHook - - jsonMarshal utils.JSONMarshal - jsonUnmarshal utils.JSONUnmarshal - xmlMarshal utils.XMLMarshal - xmlUnmarshal utils.XMLUnmarshal - - cookieJar *CookieJar - - // proxy - proxyURL string - - // retry - retryConfig *RetryConfig - - // logger - logger log.CommonLogger -} -``` - - New - -New creates and returns a new Client object. - -```go title="Signature" -func New() *Client -``` - -## REST Methods - -### Get - -Get provides an API like axios which sends a get request. - -```go title="Signature" -func (c *Client) Get(url string, cfg ...Config) (*Response, error) -``` - -### Post - -Post provides an API like axios which send post request. - -```go title="Signature" -func (c *Client) Post(url string, cfg ...Config) (*Response, error) -``` - -### Put - -Put provides an API like axios which send put request. - -```go title="Signature" -func (c *Client) Put(url string, cfg ...Config) (*Response, error) -``` - -### Patch - -Patch provides an API like axios which send patch request. - -```go title="Signature" -func (c *Client) Patch(url string, cfg ...Config) (*Response, error) -``` - -### Delete - -Delete provides an API like axios which send delete request. - -```go title="Signature" -func (c *Client) Delete(url string, cfg ...Config) (*Response, error) -``` - -### Head - -Head provides an API like axios which send head request. - -```go title="Signature" -func (c *Client) Head(url string, cfg ...Config) (*Response, error) -``` - -### Options - -Options provides an API like axios which send options request. - -```go title="Signature" -func (c *Client) Options(url string, cfg ...Config) (*Response, error) -``` - -### Custom - -Custom provides an API like axios which send custom request. - -```go title="Signature" -func (c *Client) Custom(url, method string, cfg ...Config) (*Response, error) -``` - -## Request Configuration - -Config for easy to set the request parameters, it should be noted that when setting the request body will use JSON as the default serialization mechanism, while the priority of Body is higher than FormData, and the priority of FormData is higher than File. - -It can be used to configure request data while sending requests using Get, Post, etc. - -```go -type Config struct { - Ctx context.Context - - UserAgent string - Referer string - Header map[string]string - Param map[string]string - Cookie map[string]string - PathParam map[string]string - - Timeout time.Duration - MaxRedirects int - - Body any - FormData map[string]string - File []*File -} -``` - -### R - -R raise a request from the client. -It acquires a request from the pool. You have to release it using `ReleaseRequest()` when it's no longer needed. - -```go title="Signature" -func (c *Client) R() *Request -``` - -### Hooks - -#### RequestHook - -RequestHook Request returns user-defined request hooks. - -```go title="Signature" -func (c *Client) RequestHook() []RequestHook -``` - -#### ResponseHook - -ResponseHook return user-define response hooks. - -```go title="Signature" -func (c *Client) ResponseHook() []ResponseHook -``` - -#### AddRequestHook - -AddRequestHook Add user-defined request hooks. - -```go title="Signature" -func (c *Client) AddRequestHook(h ...RequestHook) *Client -``` - -#### AddResponseHook - -AddResponseHook Add user-defined response hooks. - -```go title="Signature" -func (c *Client) AddResponseHook(h ...ResponseHook) *Client -``` - -### JSON - -#### JSONMarshal - -JSONMarshal returns json marshal function in Core. - -```go title="Signature" -func (c *Client) JSONMarshal() utils.JSONMarshal -``` - -#### JSONUnmarshal - -JSONUnmarshal returns json unmarshal function in Core. - -```go title="Signature" -func (c *Client) JSONUnmarshal() utils.JSONUnmarshal -``` - -#### SetJSONMarshal - -SetJSONMarshal sets the JSON encoder. - -```go title="Signature" -func (c *Client) SetJSONMarshal(f utils.JSONMarshal) *Client -``` - -#### SetJSONUnmarshal - -Set the JSON decoder. - -```go title="Signature" -func (c *Client) SetJSONUnmarshal(f utils.JSONUnmarshal) *Client -``` - -### XML - -#### XMLMarshal - -XMLMarshal returns xml marshal function in Core. - -```go title="Signature" -func (c *Client) XMLMarshal() utils.XMLMarshal -``` - -#### XMLUnmarshal - -XMLUnmarshal returns xml unmarshal function in Core. - -```go title="Signature" -func (c *Client) XMLUnmarshal() utils.XMLUnmarshal -``` - -#### SetXMLMarshal - -SetXMLMarshal sets the XML encoder. - -```go title="Signature" -func (c *Client) SetXMLMarshal(f utils.XMLMarshal) *Client -``` - -#### SetXMLUnmarshal - -SetXMLUnmarshal sets the XML decoder. - -```go title="Signature" -func (c *Client) SetXMLUnmarshal(f utils.XMLUnmarshal) *Client -``` - -### TLS - -#### TLSConfig - -TLSConfig returns tlsConfig in client. -If the client doesn't have a tlsConfig, this function will initialize it. - -```go title="Signature" -func (c *Client) TLSConfig() *tls.Config -``` - -#### SetTLSConfig - -SetTLSConfig sets tlsConfig in client. - -```go title="Signature" -func (c *Client) SetTLSConfig(config *tls.Config) *Client -``` - -#### SetCertificates - -SetCertificates method sets client certificates into client. - -```go title="Signature" -func (c *Client) SetCertificates(certs ...tls.Certificate) *Client -``` - -#### SetRootCertificate - -SetRootCertificate adds one or more root certificates into client. - -```go title="Signature" -func (c *Client) SetRootCertificate(path string) *Client -``` - -#### SetRootCertificateFromString - -SetRootCertificateFromString method adds one or more root certificates into the client. - -```go title="Signature" -func (c *Client) SetRootCertificateFromString(pem string) *Client -``` - -### SetProxyURL - -SetProxyURL sets proxy url in client. It will apply via core to hostclient. - -```go title="Signature" -func (c *Client) SetProxyURL(proxyURL string) error -``` - -### RetryConfig - -RetryConfig returns retry config in client. - -```go title="Signature" -func (c *Client) RetryConfig() *RetryConfig -``` - -### SetRetryConfig - -SetRetryConfig sets retry config in client, which is impl by addon/retry package. - -```go title="Signature" -func (c *Client) SetRetryConfig(config *RetryConfig) *Client -``` - -### BaseURL - -BaseURL returns baseurl in Client instance. - -```go title="Signature" -func (c *Client) BaseURL() string -``` - -### SetBaseURL - -SetBaseURL Set baseUrl which is prefix of real url. - -```go title="Signature" -func (c *Client) SetBaseURL(url string) *Client -``` - -```go title="Example" -cc := client.New() -cc.SetBaseURL("https://httpbin.org/") - -resp, err := cc.Get("/get") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -``` -{ - "args": {}, - ... -} -``` -
- -### Header - -Header method returns header value via key, this method will visit all field in the header - -```go title="Signature" -func (c *Client) Header(key string) []string -``` - -#### AddHeader - -AddHeader method adds a single header field and its value in the client instance. -These headers will be applied to all requests raised from this client instance. -Also, it can be overridden at request level header options. - -```go title="Signature" -func (c *Client) AddHeader(key, val string) *Client -``` - -#### SetHeader - -SetHeader method sets a single header field and its value in the client instance. -These headers will be applied to all requests raised from this client instance. -Also, it can be overridden at request level header options. - -```go title="Signature" -func (c *Client) SetHeader(key, val string) *Client -``` - -#### AddHeaders - -AddHeaders method adds multiple headers field and its values at one go in the client instance. -These headers will be applied to all requests raised from this client instance. -Also it can be overridden at request level headers options. - -```go title="Signature" -func (c *Client) AddHeaders(h map[string][]string) *Client -``` - -#### SetHeaders - -SetHeaders method sets multiple headers field and its values at one go in the client instance. -These headers will be applied to all requests raised from this client instance. -Also it can be overridden at request level headers options. - -```go title="Signature" -func (c *Client) SetHeaders(h map[string]string) *Client -``` - -### Param - -Param method returns params value via key, this method will visit all field in the query param. - -```go title="Signature" -func (c *Client) Param(key string) []string -``` - -#### AddParam - -AddParam method adds a single query param field and its value in the client instance. -These params will be applied to all requests raised from this client instance. -Also, it can be overridden at request level param options. - -```go title="Signature" -func (c *Client) AddParam(key, val string) *Client -``` - -#### SetParam - -SetParam method sets a single query param field and its value in the client instance. -These params will be applied to all requests raised from this client instance. -Also, it can be overridden at request level param options. - -```go title="Signature" -func (c *Client) SetParam(key, val string) *Client -``` - -#### AddParams - -AddParams method adds multiple query params field and its values at one go in the client instance. -These params will be applied to all requests raised from this client instance. -Also it can be overridden at request level params options. - -```go title="Signature" -func (c *Client) AddParams(m map[string][]string) *Client -``` - -#### SetParams - -SetParams method sets multiple params field and its values at one go in the client instance. -These params will be applied to all requests raised from this client instance. -Also it can be overridden at request level params options. - -```go title="Signature" -func (c *Client) SetParams(m map[string]string) *Client -``` - -#### SetParamsWithStruct - -SetParamsWithStruct method sets multiple params field and its values at one go in the client instance. -These params will be applied to all requests raised from this client instance. -Also it can be overridden at request level params options. - -```go title="Signature" -func (c *Client) SetParamsWithStruct(v any) *Client -``` - -#### DelParams - -DelParams method deletes single or multiple params field and its values in client. - -```go title="Signature" -func (c *Client) DelParams(key ...string) *Client -``` - -### SetUserAgent - -SetUserAgent method sets the userAgent field and its value in the client instance. -This ua will be applied to all requests raised from this client instance. -Also it can be overridden at request level ua options. - -```go title="Signature" -func (c *Client) SetUserAgent(ua string) *Client -``` - -### SetReferer - -SetReferer method sets referer field and its value in the client instance. -This referer will be applied to all requests raised from this client instance. -Also it can be overridden at request level referer options. - -```go title="Signature" -func (c *Client) SetReferer(r string) *Client -``` - -### PathParam - -PathParam returns the path param be set in request instance. -If the path param doesn't exist, return empty string. - -```go title="Signature" -func (c *Client) PathParam(key string) string -``` - -#### SetPathParam - -SetPathParam method sets a single path param field and its value in the client instance. -These path params will be applied to all requests raised from this client instance. -Also it can be overridden at request level path params options. - -```go title="Signature" -func (c *Client) SetPathParam(key, val string) *Client -``` - -#### SetPathParams - -SetPathParams method sets multiple path params field and its values at one go in the client instance. -These path params will be applied to all requests raised from this client instance. -Also it can be overridden at request level path params options. - -```go title="Signature" -func (c *Client) SetPathParams(m map[string]string) *Client -``` - -#### SetPathParamsWithStruct - -SetPathParamsWithStruct method sets multiple path params field and its values at one go in the client instance. -These path params will be applied to all requests raised from this client instance. -Also it can be overridden at request level path params options. - -```go title="Signature" -func (c *Client) SetPathParamsWithStruct(v any) *Client -``` - -#### DelPathParams - -DelPathParams method deletes single or multiple path params field and its values in client. - -```go title="Signature" -func (c *Client) DelPathParams(key ...string) *Client -``` - -### Cookie - -Cookie returns the cookie be set in request instance. -If cookie doesn't exist, return empty string. - -```go title="Signature" -func (c *Client) Cookie(key string) string -``` - -#### SetCookie - -SetCookie method sets a single cookie field and its value in the client instance. -These cookies will be applied to all requests raised from this client instance. -Also it can be overridden at request level cookie options. - -```go title="Signature" -func (c *Client) SetCookie(key, val string) *Client -``` - -```go title="Example" -cc := client.New() -cc.SetCookie("john", "doe") - -resp, err := cc.Get("https://httpbin.org/cookies") -if err != nil { - panic(err) -} - -fmt.Println(string(resp.Body())) -``` - -
-Click here to see the result - -``` -{ - "cookies": { - "john": "doe" - } -} -``` -
- -#### SetCookies - -SetCookies method sets multiple cookies field and its values at one go in the client instance. -These cookies will be applied to all requests raised from this client instance. -Also it can be overridden at request level cookie options. - -```go title="Signature" -func (c *Client) SetCookies(m map[string]string) *Client -``` - -#### SetCookiesWithStruct - -SetCookiesWithStruct method sets multiple cookies field and its values at one go in the client instance. -These cookies will be applied to all requests raised from this client instance. -Also it can be overridden at request level cookies options. - -```go title="Signature" -func (c *Client) SetCookiesWithStruct(v any) *Client -``` - -#### DelCookies - -DelCookies method deletes single or multiple cookies field and its values in client. - -```go title="Signature" -func (c *Client) DelCookies(key ...string) *Client -``` - -### SetTimeout - -SetTimeout method sets timeout val in client instance. -This value will be applied to all requests raised from this client instance. -Also, it can be overridden at request level timeout options. - -```go title="Signature" -func (c *Client) SetTimeout(t time.Duration) *Client -``` - -### Debug - -Debug enable log debug level output. - -```go title="Signature" -func (c *Client) Debug() *Client -``` - -#### DisableDebug - -DisableDebug disables log debug level output. - -```go title="Signature" -func (c *Client) DisableDebug() *Client -``` - -### SetCookieJar - -SetCookieJar sets cookie jar in client instance. - -```go title="Signature" -func (c *Client) SetCookieJar(cookieJar *CookieJar) *Client -``` - -### SetDial - -SetDial sets dial function in client. - -```go title="Signature" -func (c *Client) SetDial(dial fasthttp.DialFunc) *Client -``` - -### SetLogger - -SetLogger sets logger instance in client. - -```go title="Signature" -func (c *Client) SetLogger(logger log.CommonLogger) *Client -``` - -### Logger - -Logger returns logger instance of client. - -```go title="Signature" -func (c *Client) Logger() log.CommonLogger -``` - -### Reset - -Reset clears the Client object - -```go title="Signature" -func (c *Client) Reset() -``` - -## Default Client - -Default client is default client object of Gofiber and created using `New()`. -You can configurate it as you wish or replace it with another clients. - -### C - -C gets default client. - -```go title="Signature" -func C() *Client -``` - -### Get - -Get is a convenience method that sends a GET request using the `defaultClient`. - -```go title="Signature" -func Get(url string, cfg ...Config) (*Response, error) -``` - -### Post - -Post is a convenience method that sends a POST request using the `defaultClient`. - -```go title="Signature" -func Post(url string, cfg ...Config) (*Response, error) -``` - -### Put - -Put is a convenience method that sends a PUT request using the `defaultClient`. - -```go title="Signature" -func Put(url string, cfg ...Config) (*Response, error) -``` - -### Patch - -Patch is a convenience method that sends a PATCH request using the `defaultClient`. - -```go title="Signature" -func Patch(url string, cfg ...Config) (*Response, error) -``` - -### Delete - -Delete is a convenience method that sends a DELETE request using the `defaultClient`. - -```go title="Signature" -func Delete(url string, cfg ...Config) (*Response, error) -``` - -### Head - -Head sends a HEAD request using the `defaultClient`, a convenience method. - -```go title="Signature" -func Head(url string, cfg ...Config) (*Response, error) -``` - -### Options - -Options is a convenience method that sends an OPTIONS request using the `defaultClient`. - -```go title="Signature" -func Options(url string, cfg ...Config) (*Response, error) -``` - -### Replace - -Replace the defaultClient, the returned function can undo. - -:::caution -The default client should not be changed concurrently. -::: - -```go title="Signature" -func Replace(c *Client) func() -``` diff --git a/versioned_docs/version-v3.x/extra/_category_.json b/versioned_docs/version-v3.x/extra/_category_.json deleted file mode 100644 index 3398bed555f..00000000000 --- a/versioned_docs/version-v3.x/extra/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "\uD83E\uDDE9 Extra", - "position": 6, - "link": { - "type": "generated-index", - "description": "Extra contents for Fiber." - } -} diff --git a/versioned_docs/version-v3.x/extra/benchmarks.md b/versioned_docs/version-v3.x/extra/benchmarks.md deleted file mode 100644 index 3c2a82037dd..00000000000 --- a/versioned_docs/version-v3.x/extra/benchmarks.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -id: benchmarks -title: πŸ“Š Benchmarks -description: >- - These benchmarks aim to compare the performance of Fiber and other web - frameworks. -sidebar_position: 2 ---- - -## TechEmpower - -[TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=composite) provides a performance comparison of many web application frameworks executing fundamental tasks such as JSON serialization, database access, and server-side template composition. - -Each framework is operating in a realistic production configuration. Results are captured on cloud instances and on physical hardware. The test implementations are largely community-contributed and all source is available at the [GitHub repository](https://github.com/TechEmpower/FrameworkBenchmarks). - -* Fiber `v1.10.0` -* 28 HT Cores Intel\(R\) Xeon\(R\) Gold 5120 CPU @ 2.20GHz -* 32GB RAM -* Ubuntu 18.04.3 4.15.0-88-generic -* Dedicated Cisco 10-Gbit Ethernet switch. - -### Plaintext - -The Plaintext test is an exercise of the request-routing fundamentals only, designed to demonstrate the capacity of high-performance platforms in particular. Requests will be sent using HTTP pipelining. The response payload is still small, meaning good performance is still necessary in order to saturate the gigabit Ethernet of the test environment. - -See [Plaintext requirements](https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#single-database-query) - -**Fiber** - **6,162,556** responses per second with an average latency of **2.0** ms. -**Express** - **367,069** responses per second with an average latency of **354.1** ms. - -![](/img/plaintext.png) - -![Fiber vs Express](/img/plaintext_express.png) - -### Data Updates - -**Fiber** handled **11,846** responses per second with an average latency of **42.8** ms. -**Express** handled **2,066** responses per second with an average latency of **390.44** ms. - -![](/img/data_updates.png) - -![Fiber vs Express](/img/data_updates_express.png) - -### Multiple Queries - -**Fiber** handled **19,664** responses per second with an average latency of **25.7** ms. -**Express** handled **4,302** responses per second with an average latency of **117.2** ms. - -![](/img/multiple_queries.png) - -![Fiber vs Express](/img/multiple_queries_express.png) - -### Single Query - -**Fiber** handled **368,647** responses per second with an average latency of **0.7** ms. -**Express** handled **57,880** responses per second with an average latency of **4.4** ms. - -![](/img/single_query.png) - -![Fiber vs Express](/img/single_query_express.png) - -### JSON Serialization - -**Fiber** handled **1,146,667** responses per second with an average latency of **0.4** ms. -**Express** handled **244,847** responses per second with an average latency of **1.1** ms. - -![](/img/json.png) - -![Fiber vs Express](/img/json_express.png) - -## Go web framework benchmark - -πŸ”— [https://github.com/smallnest/go-web-framework-benchmark](https://github.com/smallnest/go-web-framework-benchmark) - -* **CPU** Intel\(R\) Xeon\(R\) Gold 6140 CPU @ 2.30GHz -* **MEM** 4GB -* **GO** go1.13.6 linux/amd64 -* **OS** Linux - -The first test case is to mock **0 ms**, **10 ms**, **100 ms**, **500 ms** processing time in handlers. - -![](/img/benchmark.png) - -The concurrency clients are **5000**. - -![](/img/benchmark_latency.png) - -Latency is the time of real processing time by web servers. _The smaller is the better._ - -![](/img/benchmark_alloc.png) - -Allocs is the heap allocations by web servers when test is running. The unit is MB. _The smaller is the better._ - -If we enable **http pipelining**, test result as below: - -![](/img/benchmark-pipeline.png) - -Concurrency test in **30 ms** processing time, the test result for **100**, **1000**, **5000** clients is: - -![](/img/concurrency.png) - -![](/img/concurrency_latency.png) - -![](/img/concurrency_alloc.png) - -If we enable **http pipelining**, test result as below: - -![](/img/concurrency-pipeline.png) - -Dependency graph for `v1.9.0` - -![](/img/graph.svg) diff --git a/versioned_docs/version-v3.x/extra/faq.md b/versioned_docs/version-v3.x/extra/faq.md deleted file mode 100644 index eaea2a2c419..00000000000 --- a/versioned_docs/version-v3.x/extra/faq.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -id: faq -title: πŸ€” FAQ -description: >- - List of frequently asked questions. Feel free to open an issue to add your - question to this page. -sidebar_position: 1 ---- - -## How should I structure my application? - -There is no definitive answer to this question. The answer depends on the scale of your application and the team that is involved. To be as flexible as possible, Fiber makes no assumptions in terms of structure. - -Routes and other application-specific logic can live in as many files as you wish, in any directory structure you prefer. View the following examples for inspiration: - -* [gofiber/boilerplate](https://github.com/gofiber/boilerplate) -* [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate) -* [Youtube - Building a REST API using Gorm and Fiber](https://www.youtube.com/watch?v=Iq2qT0fRhAA) -* [embedmode/fiberseed](https://github.com/embedmode/fiberseed) - -## How do I handle custom 404 responses? - -If you're using v2.32.0 or later, all you need to do is to implement a custom error handler. See below, or see a more detailed explanation at [Error Handling](../guide/error-handling.md#custom-error-handler). - -If you're using v2.31.0 or earlier, the error handler will not capture 404 errors. Instead, you need to add a middleware function at the very bottom of the stack \(below all other functions\) to handle a 404 response: - -```go title="Example" -app.Use(func(c fiber.Ctx) error { - return c.Status(fiber.StatusNotFound).SendString("Sorry can't find that!") -}) -``` - -## How can i use live reload ? - -[Air](https://github.com/cosmtrek/air) is a handy tool that automatically restarts your Go applications whenever the source code changes, making your development process faster and more efficient. - -To use Air in a Fiber project, follow these steps: - -1. Install Air by downloading the appropriate binary for your operating system from the GitHub release page or by building the tool directly from source. -2. Create a configuration file for Air in your project directory. This file can be named, for example, .air.toml or air.conf. Here's a sample configuration file that works with Fiber: -```toml -# .air.toml -root = "." -tmp_dir = "tmp" -[build] - cmd = "go build -o ./tmp/main ." - bin = "./tmp/main" - delay = 1000 # ms - exclude_dir = ["assets", "tmp", "vendor"] - include_ext = ["go", "tpl", "tmpl", "html"] - exclude_regex = ["_test\\.go"] -``` -3. Start your Fiber application using Air by running the following command in the terminal: -```sh -air -``` - -As you make changes to your source code, Air will detect them and automatically restart the application. - -A complete example demonstrating the use of Air with Fiber can be found in the [Fiber Recipes repository](https://github.com/gofiber/recipes/tree/master/air). This example shows how to configure and use Air in a Fiber project to create an efficient development environment. - - -## How do I set up an error handler? - -To override the default error handler, you can override the default when providing a [Config](../api/fiber.md#errorhandler) when initiating a new [Fiber instance](../api/fiber.md#new). - -```go title="Example" -app := fiber.New(fiber.Config{ - ErrorHandler: func(c fiber.Ctx, err error) error { - return c.Status(fiber.StatusInternalServerError).SendString(err.Error()) - }, -}) -``` - -We have a dedicated page explaining how error handling works in Fiber, see [Error Handling](../guide/error-handling.md). - -## Which template engines does Fiber support? - -Fiber currently supports 9 template engines in our [gofiber/template](https://docs.gofiber.io/template/) middleware: - -* [ace](https://docs.gofiber.io/template/ace/) -* [amber](https://docs.gofiber.io/template/amber/) -* [django](https://docs.gofiber.io/template/django/) -* [handlebars](https://docs.gofiber.io/template/handlebars) -* [html](https://docs.gofiber.io/template/html) -* [jet](https://docs.gofiber.io/template/jet) -* [mustache](https://docs.gofiber.io/template/mustache) -* [pug](https://docs.gofiber.io/template/pug) -* [slim](https://docs.gofiber.io/template/slim) - -To learn more about using Templates in Fiber, see [Templates](../guide/templates.md). - -## Does Fiber have a community chat? - -Yes, we have our own [Discord ](https://gofiber.io/discord)server, where we hang out. We have different rooms for every subject. -If you have questions or just want to have a chat, feel free to join us via this **>** [**invite link**](https://gofiber.io/discord) **<**. - -![](/img/support-discord.png) - -## Does fiber support sub domain routing ? - -Yes we do, here are some examples: -This example works v2 -```go -package main - -import ( - "log" - - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/logger" -) - -type Host struct { - Fiber *fiber.App -} - -func main() { - // Hosts - hosts := map[string]*Host{} - //----- - // API - //----- - api := fiber.New() - api.Use(logger.New(logger.Config{ - Format: "[${ip}]:${port} ${status} - ${method} ${path}\n", - })) - hosts["api.localhost:3000"] = &Host{api} - api.Get("/", func(c fiber.Ctx) error { - return c.SendString("API") - }) - //------ - // Blog - //------ - blog := fiber.New() - blog.Use(logger.New(logger.Config{ - Format: "[${ip}]:${port} ${status} - ${method} ${path}\n", - })) - hosts["blog.localhost:3000"] = &Host{blog} - blog.Get("/", func(c fiber.Ctx) error { - return c.SendString("Blog") - }) - //--------- - // Website - //--------- - site := fiber.New() - site.Use(logger.New(logger.Config{ - Format: "[${ip}]:${port} ${status} - ${method} ${path}\n", - })) - - hosts["localhost:3000"] = &Host{site} - site.Get("/", func(c fiber.Ctx) error { - return c.SendString("Website") - }) - // Server - app := fiber.New() - app.Use(func(c fiber.Ctx) error { - host := hosts[c.Hostname()] - if host == nil { - return c.SendStatus(fiber.StatusNotFound) - } else { - host.Fiber.Handler()(c.Context()) - return nil - } - }) - log.Fatal(app.Listen(":3000")) -} -``` -If more information is needed, please refer to this issue [#750](https://github.com/gofiber/fiber/issues/750) diff --git a/versioned_docs/version-v3.x/guide/_category_.json b/versioned_docs/version-v3.x/guide/_category_.json deleted file mode 100644 index 62226d5d68e..00000000000 --- a/versioned_docs/version-v3.x/guide/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "\uD83D\uDCD6 Guide", - "position": 5, - "link": { - "type": "generated-index", - "description": "Guides for Fiber." - } -} diff --git a/versioned_docs/version-v3.x/guide/error-handling.md b/versioned_docs/version-v3.x/guide/error-handling.md deleted file mode 100644 index 584f28eda20..00000000000 --- a/versioned_docs/version-v3.x/guide/error-handling.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -id: error-handling -title: πŸ› Error Handling -description: >- - Fiber supports centralized error handling by returning an error to the handler - which allows you to log errors to external services or send a customized HTTP - response to the client. -sidebar_position: 4 ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -## Catching Errors - -It’s essential to ensure that Fiber catches all errors that occur while running route handlers and middleware. You must return them to the handler function, where Fiber will catch and process them. - - - - -```go -app.Get("/", func(c fiber.Ctx) error { - // Pass error to Fiber - return c.SendFile("file-does-not-exist") -}) -``` - - - -Fiber does not handle [panics](https://go.dev/blog/defer-panic-and-recover) by default. To recover from a panic thrown by any handler in the stack, you need to include the `Recover` middleware below: - -```go title="Example" -package main - -import ( - "log" - - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/recover" -) - -func main() { - app := fiber.New() - - app.Use(recover.New()) - - app.Get("/", func(c fiber.Ctx) error { - panic("This panic is caught by fiber") - }) - - log.Fatal(app.Listen(":3000")) -} -``` - -You could use Fiber's custom error struct to pass an additional `status code` using `fiber.NewError()`. It's optional to pass a message; if this is left empty, it will default to the status code message \(`404` equals `Not Found`\). - -```go title="Example" -app.Get("/", func(c fiber.Ctx) error { - // 503 Service Unavailable - return fiber.ErrServiceUnavailable - - // 503 On vacation! - return fiber.NewError(fiber.StatusServiceUnavailable, "On vacation!") -}) -``` - -## Default Error Handler - -Fiber provides an error handler by default. For a standard error, the response is sent as **500 Internal Server Error**. If the error is of type [fiber.Error](https://godoc.org/github.com/gofiber/fiber#Error), the response is sent with the provided status code and message. - -```go title="Example" -// Default error handler -var DefaultErrorHandler = func(c fiber.Ctx, err error) error { - // Status code defaults to 500 - code := fiber.StatusInternalServerError - - // Retrieve the custom status code if it's a *fiber.Error - var e *fiber.Error - if errors.As(err, &e) { - code = e.Code - } - - // Set Content-Type: text/plain; charset=utf-8 - c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8) - - // Return status code with error message - return c.Status(code).SendString(err.Error()) -} -``` - -## Custom Error Handler - -A custom error handler can be set using a [Config](../api/fiber.md#errorhandler) when initializing a [Fiber instance](../api/fiber.md#new). - -In most cases, the default error handler should be sufficient. However, a custom error handler can come in handy if you want to capture different types of errors and take action accordingly e.g., send a notification email or log an error to the centralized system. You can also send customized responses to the client e.g., error page or just a JSON response. - -The following example shows how to display error pages for different types of errors. - -```go title="Example" -// Create a new fiber instance with custom config -app := fiber.New(fiber.Config{ - // Override default error handler - ErrorHandler: func(ctx fiber.Ctx, err error) error { - // Status code defaults to 500 - code := fiber.StatusInternalServerError - - // Retrieve the custom status code if it's a *fiber.Error - var e *fiber.Error - if errors.As(err, &e) { - code = e.Code - } - - // Send custom error page - err = ctx.Status(code).SendFile(fmt.Sprintf("./%d.html", code)) - if err != nil { - // In case the SendFile fails - return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error") - } - - // Return from handler - return nil - }, -}) - -// ... -``` - -> Special thanks to the [Echo](https://echo.labstack.com/) & [Express](https://expressjs.com/) framework for inspiration regarding error handling. diff --git a/versioned_docs/version-v3.x/guide/faster-fiber.md b/versioned_docs/version-v3.x/guide/faster-fiber.md deleted file mode 100644 index d4c2df1b891..00000000000 --- a/versioned_docs/version-v3.x/guide/faster-fiber.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -id: faster-fiber -title: ⚑ Make Fiber Faster -sidebar_position: 7 ---- - -## Custom JSON Encoder/Decoder -Since Fiber v2.32.0, we use **encoding/json** as default json library due to stability and producibility. However, the standard library is a bit slow compared to 3rd party libraries. If you're not happy with the performance of **encoding/json**, we recommend you to use these libraries: -- [goccy/go-json](https://github.com/goccy/go-json) -- [bytedance/sonic](https://github.com/bytedance/sonic) -- [segmentio/encoding](https://github.com/segmentio/encoding) -- [mailru/easyjson](https://github.com/mailru/easyjson) -- [minio/simdjson-go](https://github.com/minio/simdjson-go) -- [wI2L/jettison](https://github.com/wI2L/jettison) - -```go title="Example" -package main - -import "github.com/gofiber/fiber/v3" -import "github.com/goccy/go-json" - -func main() { - app := fiber.New(fiber.Config{ - JSONEncoder: json.Marshal, - JSONDecoder: json.Unmarshal, - }) - - # ... -} -``` - -### References - -- [Set custom JSON encoder for client](../client/rest.md#setjsonmarshal) -- [Set custom JSON decoder for client](../client/rest.md#setjsonunmarshal) -- [Set custom JSON encoder for application](../api/fiber.md#jsonencoder) -- [Set custom JSON decoder for application](../api/fiber.md#jsondecoder) diff --git a/versioned_docs/version-v3.x/guide/grouping.md b/versioned_docs/version-v3.x/guide/grouping.md deleted file mode 100644 index 4ed4622c184..00000000000 --- a/versioned_docs/version-v3.x/guide/grouping.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -id: grouping -title: 🎭 Grouping -sidebar_position: 2 ---- - -:::info -In general, the Group functionality in Fiber behaves similarly to ExpressJS. Groups are declared virtually and all routes declared within the group are flattened into a single list with a prefix, which is then checked by the framework in the order it was declared. This means that the behavior of Group in Fiber is identical to that of ExpressJS. -::: - -## Paths - -Like **Routing**, groups can also have paths that belong to a cluster. - -```go -func main() { - app := fiber.New() - - api := app.Group("/api", middleware) // /api - - v1 := api.Group("/v1", middleware) // /api/v1 - v1.Get("/list", handler) // /api/v1/list - v1.Get("/user", handler) // /api/v1/user - - v2 := api.Group("/v2", middleware) // /api/v2 - v2.Get("/list", handler) // /api/v2/list - v2.Get("/user", handler) // /api/v2/user - - log.Fatal(app.Listen(":3000")) -} -``` - -A **Group** of paths can have an optional handler. - -```go -func main() { - app := fiber.New() - - api := app.Group("/api") // /api - - v1 := api.Group("/v1") // /api/v1 - v1.Get("/list", handler) // /api/v1/list - v1.Get("/user", handler) // /api/v1/user - - v2 := api.Group("/v2") // /api/v2 - v2.Get("/list", handler) // /api/v2/list - v2.Get("/user", handler) // /api/v2/user - - log.Fatal(app.Listen(":3000")) -} -``` - -:::caution -Running **/api**, **/v1** or **/v2** will result in **404** error, make sure you have the errors set. -::: - -## Group Handlers - -Group handlers can also be used as a routing path but they must have **Next** added to them so that the flow can continue. - -```go -func main() { - app := fiber.New() - - handler := func(c fiber.Ctx) error { - return c.SendStatus(fiber.StatusOK) - } - api := app.Group("/api") // /api - - v1 := api.Group("/v1", func(c fiber.Ctx) error { // middleware for /api/v1 - c.Set("Version", "v1") - return c.Next() - }) - v1.Get("/list", handler) // /api/v1/list - v1.Get("/user", handler) // /api/v1/user - - log.Fatal(app.Listen(":3000")) -} -``` diff --git a/versioned_docs/version-v3.x/guide/routing.md b/versioned_docs/version-v3.x/guide/routing.md deleted file mode 100644 index 7dcc2b61e76..00000000000 --- a/versioned_docs/version-v3.x/guide/routing.md +++ /dev/null @@ -1,348 +0,0 @@ ---- -id: routing -title: πŸ”Œ Routing -description: >- - Routing refers to how an application's endpoints (URIs) respond to client - requests. -sidebar_position: 1 -toc_max_heading_level: 4 ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import RoutingHandler from './../partials/routing/handler.md'; - -## Handlers - - - -## Paths - -Route paths, combined with a request method, define the endpoints at which requests can be made. Route paths can be **strings** or **string patterns**. - -**Examples of route paths based on strings** - -```go -// This route path will match requests to the root route, "/": -app.Get("/", func(c fiber.Ctx) error { - return c.SendString("root") -}) - -// This route path will match requests to "/about": -app.Get("/about", func(c fiber.Ctx) error { - return c.SendString("about") -}) - -// This route path will match requests to "/random.txt": -app.Get("/random.txt", func(c fiber.Ctx) error { - return c.SendString("random.txt") -}) -``` - -As with the expressJs framework, the order of the route declaration plays a role. -When a request is received, the routes are checked in the order in which they are declared. - -:::info -So please be careful to write routes with variable parameters after the routes that contain fixed parts, so that these variable parts do not match instead and unexpected behavior occurs. -::: - -## Parameters - -Route parameters are dynamic elements in the route, which are **named** or **not named segments**. This segments that are used to capture the values specified at their position in the URL. The obtained values can be retrieved using the [Params](https://fiber.wiki/context#params) function, with the name of the route parameter specified in the path as their respective keys or for unnamed parameters the character\(\*, +\) and the counter of this. - -The characters :, +, and \* are characters that introduce a parameter. - -Greedy parameters are indicated by wildcard\(\*\) or plus\(+\) signs. - -The routing also offers the possibility to use optional parameters, for the named parameters these are marked with a final "?", unlike the plus sign which is not optional, you can use the wildcard character for a parameter range which is optional and greedy. - -**Example of define routes with route parameters** - -```go -// Parameters -app.Get("/user/:name/books/:title", func(c fiber.Ctx) error { - fmt.Fprintf(c, "%s\n", c.Params("name")) - fmt.Fprintf(c, "%s\n", c.Params("title")) - return nil -}) -// Plus - greedy - not optional -app.Get("/user/+", func(c fiber.Ctx) error { - return c.SendString(c.Params("+")) -}) - -// Optional parameter -app.Get("/user/:name?", func(c fiber.Ctx) error { - return c.SendString(c.Params("name")) -}) - -// Wildcard - greedy - optional -app.Get("/user/*", func(c fiber.Ctx) error { - return c.SendString(c.Params("*")) -}) - -// This route path will match requests to "/v1/some/resource/name:customVerb", since the parameter character is escaped -app.Get(`/v1/some/resource/name\:customVerb`, func(c fiber.Ctx) error { - return c.SendString("Hello, Community") -}) -``` - -:::info -Since the hyphen \(`-`\) and the dot \(`.`\) are interpreted literally, they can be used along with route parameters for useful purposes. -::: - -:::info -All special parameter characters can also be escaped with `"\\"` and lose their value, so you can use them in the route if you want, like in the custom methods of the [google api design guide](https://cloud.google.com/apis/design/custom_methods). It's recommended to use backticks `` ` `` because in go's regex documentation, they always use backticks to make sure it is unambiguous and the escape character doesn't interfere with regex patterns in an unexpected way. -::: - -```go -// http://localhost:3000/plantae/prunus.persica -app.Get("/plantae/:genus.:species", func(c fiber.Ctx) error { - fmt.Fprintf(c, "%s.%s\n", c.Params("genus"), c.Params("species")) - return nil // prunus.persica -}) -``` - -```go -// http://localhost:3000/flights/LAX-SFO -app.Get("/flights/:from-:to", func(c fiber.Ctx) error { - fmt.Fprintf(c, "%s-%s\n", c.Params("from"), c.Params("to")) - return nil // LAX-SFO -}) -``` - -Our intelligent router recognizes that the introductory parameter characters should be part of the request route in this case and can process them as such. - -```go -// http://localhost:3000/shop/product/color:blue/size:xs -app.Get("/shop/product/color::color/size::size", func(c fiber.Ctx) error { - fmt.Fprintf(c, "%s:%s\n", c.Params("color"), c.Params("size")) - return nil // blue:xs -}) -``` - -In addition, several parameters in a row and several unnamed parameter characters in the route, such as the wildcard or plus character, are possible, which greatly expands the possibilities of the router for the user. - -```go -// GET /@v1 -// Params: "sign" -> "@", "param" -> "v1" -app.Get("/:sign:param", handler) - -// GET /api-v1 -// Params: "name" -> "v1" -app.Get("/api-:name", handler) - -// GET /customer/v1/cart/proxy -// Params: "*1" -> "customer/", "*2" -> "/cart" -app.Get("/*v1*/proxy", handler) - -// GET /v1/brand/4/shop/blue/xs -// Params: "*1" -> "brand/4", "*2" -> "blue/xs" -app.Get("/v1/*/shop/*", handler) -``` - -We have adapted the routing strongly to the express routing, but currently without the possibility of the regular expressions, because they are quite slow. The possibilities can be tested with version 0.1.7 \(express 4\) in the online [Express route tester](http://forbeslindesay.github.io/express-route-tester/). - -### Constraints -Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values by parameters. The feature was introduced in `v2.37.0` and inspired by [.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-6.0#route-constraints). - -:::caution -Constraints aren't validation for parameters. If constraints aren't valid for a parameter value, Fiber returns **404 handler**. -::: - -| Constraint | Example | Example matches | -| ----------------- | ------------------------------------ | ------------------------------------------------------------------------------------------- | -| int | `:id` | 123456789, -123456789 | -| bool | `:active` | true,false | -| guid | `:id` | CD2C1638-1638-72D5-1638-DEADBEEF1638 | -| float | `:weight` | 1.234, -1,001.01e8 | -| minLen(value) | `:username` | Test (must be at least 4 characters) | -| maxLen(value) | `:filename` | MyFile (must be no more than 8 characters | -| len(length) | `:filename` | somefile.txt (exactly 12 characters) | -| min(value) | `:age` | 19 (Integer value must be at least 18) | -| max(value) | `:age` | 91 (Integer value must be no more than 120) | -| range(min,max) | `:age` | 91 (Integer value must be at least 18 but no more than 120) | -| alpha | `:name` | Rick (String must consist of one or more alphabetical characters, a-z and case-insensitive) | -| datetime | `:dob` | 2005-11-01 | -| regex(expression) | `:date` | 2022-08-27 (Must match regular expression) | - -#### Examples - - - - -```go -app.Get("/:test", func(c fiber.Ctx) error { - return c.SendString(c.Params("test")) -}) - -// curl -X GET http://localhost:3000/12 -// 12 - -// curl -X GET http://localhost:3000/1 -// Cannot GET /1 -``` - - - -You can use `;` for multiple constraints. -```go -app.Get("/:test", func(c fiber.Ctx) error { - return c.SendString(c.Params("test")) -}) - -// curl -X GET http://localhost:3000/120000 -// Cannot GET /120000 - -// curl -X GET http://localhost:3000/1 -// Cannot GET /1 - -// curl -X GET http://localhost:3000/250 -// 250 -``` - - - -Fiber precompiles regex query when to register routes. So there're no performance overhead for regex constraint. -```go -app.Get(`/:date`, func(c fiber.Ctx) error { - return c.SendString(c.Params("date")) -}) - -// curl -X GET http://localhost:3000/125 -// Cannot GET /125 - -// curl -X GET http://localhost:3000/test -// Cannot GET /test - -// curl -X GET http://localhost:3000/2022-08-27 -// 2022-08-27 -``` - - - - -:::caution -You should use `\\` before routing-specific characters when to use datetime constraint (`*`, `+`, `?`, `:`, `/`, `<`, `>`, `;`, `(`, `)`), to avoid wrong parsing. -::: - -#### Optional Parameter Example - -You can impose constraints on optional parameters as well. - -```go -app.Get("/:test?", func(c fiber.Ctx) error { - return c.SendString(c.Params("test")) -}) -// curl -X GET http://localhost:3000/42 -// 42 -// curl -X GET http://localhost:3000/ -// -// curl -X GET http://localhost:3000/7.0 -// Cannot GET /7.0 -``` - -#### Custom Constraint - -Custom constraints can be added to Fiber using the `app.RegisterCustomConstraint` method. Your constraints have to be compatible with the `CustomConstraint` interface. - -It is a good idea to add external constraints to your project once you want to add more specific rules to your routes. -For example, you can add a constraint to check if a parameter is a valid ULID. - -```go -// CustomConstraint is an interface for custom constraints -type CustomConstraint interface { - // Name returns the name of the constraint. - // This name is used in the constraint matching. - Name() string - - // Execute executes the constraint. - // It returns true if the constraint is matched and right. - // param is the parameter value to check. - // args are the constraint arguments. - Execute(param string, args ...string) bool -} -``` - -You can check the example below: - -```go -type UlidConstraint struct { - fiber.CustomConstraint -} - -func (*UlidConstraint) Name() string { - return "ulid" -} - -func (*UlidConstraint) Execute(param string, args ...string) bool { - _, err := ulid.Parse(param) - return err == nil -} - -func main() { - app := fiber.New() - app.RegisterCustomConstraint(&UlidConstraint{}) - - app.Get("/login/:id", func(c fiber.Ctx) error { - return c.SendString("...") - }) - - app.Listen(":3000") - - // /login/01HK7H9ZE5BFMK348CPYP14S0Z -> 200 - // /login/12345 -> 404 -} -``` - -## Middleware - -Functions that are designed to make changes to the request or response are called **middleware functions**. The [Next](../api/ctx.md#next) is a **Fiber** router function, when called, executes the **next** function that **matches** the current route. - -### Example of a middleware function - -```go -app.Use(func(c fiber.Ctx) error { - // Set a custom header on all responses: - c.Set("X-Custom-Header", "Hello, World") - - // Go to next middleware: - return c.Next() -}) - -app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") -}) -``` - -`Use` method path is a **mount**, or **prefix** path, and limits middleware to only apply to any paths requested that begin with it. - -### Constraints on Adding Routes Dynamically - -:::caution -Adding routes dynamically after the application has started is not supported due to design and performance considerations. Make sure to define all your routes before the application starts. -::: - - -## Grouping - -If you have many endpoints, you can organize your routes using `Group`. - -```go -func main() { - app := fiber.New() - - api := app.Group("/api", middleware) // /api - - v1 := api.Group("/v1", middleware) // /api/v1 - v1.Get("/list", handler) // /api/v1/list - v1.Get("/user", handler) // /api/v1/user - - v2 := api.Group("/v2", middleware) // /api/v2 - v2.Get("/list", handler) // /api/v2/list - v2.Get("/user", handler) // /api/v2/user - - log.Fatal(app.Listen(":3000")) -} -``` - -More information about this in our [Grouping Guide](./grouping.md) diff --git a/versioned_docs/version-v3.x/guide/templates.md b/versioned_docs/version-v3.x/guide/templates.md deleted file mode 100644 index 2bd441fe28b..00000000000 --- a/versioned_docs/version-v3.x/guide/templates.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: templates -title: πŸ“ Templates -description: Fiber supports server-side template engines. -sidebar_position: 3 ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -## Template interfaces - -Fiber provides a Views interface to provide your own template engine: - - - - -```go -type Views interface { - Load() error - Render(out io.Writer, name string, binding any, layout ...string) error -} -``` - - - -`Views` interface contains a `Load` and `Render` method, `Load` is executed by Fiber on app initialization to load/parse the templates. - -```go -// Pass engine to Fiber's Views Engine -app := fiber.New(fiber.Config{ - Views: engine, - // Views Layout is the global layout for all template render until override on Render function. - ViewsLayout: "layouts/main" -}) -``` - -The `Render` method is linked to the [**ctx.Render\(\)**](../api/ctx.md#render) function that accepts a template name and binding data. It will use global layout if layout is not being defined in `Render` function. -If the Fiber config option `PassLocalsToViews` is enabled, then all locals set using `ctx.Locals(key, value)` will be passed to the template. - -```go -app.Get("/", func(c fiber.Ctx) error { - return c.Render("index", fiber.Map{ - "hello": "world", - }); -}) -``` - -## Engines - -Fiber team maintains [templates](https://docs.gofiber.io/template) package that provides wrappers for multiple template engines: - -* [ace](https://docs.gofiber.io/template/ace/) -* [amber](https://docs.gofiber.io/template/amber/) -* [django](https://docs.gofiber.io/template/django/) -* [handlebars](https://docs.gofiber.io/template/handlebars) -* [html](https://docs.gofiber.io/template/html) -* [jet](https://docs.gofiber.io/template/jet) -* [mustache](https://docs.gofiber.io/template/mustache) -* [pug](https://docs.gofiber.io/template/pug) -* [slim](https://docs.gofiber.io/template/slim) - - - - -```go -package main - -import ( - "log" - "github.com/gofiber/fiber/v3" - "github.com/gofiber/template/html/v2" -) - -func main() { - // Initialize standard Go html template engine - engine := html.New("./views", ".html") - // If you want other engine, just replace with following - // Create a new engine with django - // engine := django.New("./views", ".django") - - app := fiber.New(fiber.Config{ - Views: engine, - }) - app.Get("/", func(c fiber.Ctx) error { - // Render index template - return c.Render("index", fiber.Map{ - "Title": "Hello, World!", - }) - }) - - log.Fatal(app.Listen(":3000")) -} -``` - - - -```markup - - -

{{.Title}}

- - -``` -
-
diff --git a/versioned_docs/version-v3.x/guide/utils.md b/versioned_docs/version-v3.x/guide/utils.md deleted file mode 100644 index 3dbff1ab92a..00000000000 --- a/versioned_docs/version-v3.x/guide/utils.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -id: utils -title: 🧰 Utils -sidebar_position: 8 -toc_max_heading_level: 4 ---- - -## Generics - -### Convert - -Converts a string value to a specified type, handling errors and optional default values. -This function simplifies the conversion process by encapsulating error handling and the management of default values, making your code cleaner and more consistent. - -```go title="Signature" -func Convert[T any](value string, convertor func(string) (T, error), defaultValue ...T) (*T, error) -``` - -```go title="Example" -// GET http://example.com/id/bb70ab33-d455-4a03-8d78-d3c1dacae9ff -app.Get("/id/:id", func(c fiber.Ctx) error { - fiber.Convert(c.Params("id"), uuid.Parse) // UUID(bb70ab33-d455-4a03-8d78-d3c1dacae9ff), nil - - -// GET http://example.com/search?id=65f6f54221fb90e6a6b76db7 -app.Get("/search", func(c fiber.Ctx) error) { - fiber.Convert(c.Query("id"), mongo.ParseObjectID) // objectid(65f6f54221fb90e6a6b76db7), nil - fiber.Convert(c.Query("id"), uuid.Parse) // uuid.Nil, error(cannot parse given uuid) - fiber.Convert(c.Query("id"), uuid.Parse, mongo.NewObjectID) // new object id generated and return nil as error. -} - - // ... -}) -``` - - -### GetReqHeader - -GetReqHeader function utilizing Go's generics feature. -This function allows for retrieving HTTP request headers with a more specific data type. - -```go title="Signature" -func GetReqHeader[V any](c Ctx, key string, defaultValue ...V) V -``` - -```go title="Example" -app.Get("/search", func(c fiber.Ctx) error { - // curl -X GET http://example.com/search -H "X-Request-ID: 12345" -H "X-Request-Name: John" - GetReqHeader[int](c, "X-Request-ID") // => returns 12345 as integer. - GetReqHeader[string](c, "X-Request-Name") // => returns "John" as string. - GetReqHeader[string](c, "unknownParam", "default") // => returns "default" as string. - // ... -}) -``` - -### Locals - -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. - -```go title="Signature" -func Locals[V any](c Ctx, key any, value ...V) V - -// get local value -func Locals[V any](c Ctx, key any) V -// set local value -func Locals[V any](c Ctx, key any, value ...V) V -``` - -```go title="Example" -app.Use("/user/:user/:id", func(c fiber.Ctx) error { - // set local values - fiber.Locals[string](c, "user", "john") - fiber.Locals[int](c, "id", 25) - // ... - - return c.Next() -}) - - -app.Get("/user/*", func(c fiber.Ctx) error { - // get local values - name := fiber.Locals[string](c, "user") // john - age := fiber.Locals[int](c, "id") // 25 - // ... -}) -``` - -### Params - -Params function utilizing Go's generics feature. -This function allows for retrieving route parameters with a more specific data type. - -```go title="Signature" -func Params[V any](c Ctx, key string, defaultValue ...V) V -``` - -```go title="Example" -app.Get("/user/:user/:id", func(c fiber.Ctx) error { - // http://example.com/user/john/25 - Params[int](c, "id") // => returns 25 as integer. - Params[int](c, "unknownParam", 99) // => returns the default 99 as integer. - // ... - return c.SendString("Hello, " + fiber.Params[string](c, "user")) -}) -``` - -### Query - -Query function utilizing Go's generics feature. -This function allows for retrieving query parameters with a more specific data type. - -```go title="Signature" -func Query[V any](c Ctx, key string, defaultValue ...V) V -``` - -```go title="Example" -app.Get("/search", func(c fiber.Ctx) error { - // http://example.com/search?name=john&age=25 - Query[string](c, "name") // => returns "john" - Query[int](c, "age") // => returns 25 as integer. - Query[string](c, "unknownParam", "default") // => returns "default" as string. - // ... -}) -``` diff --git a/versioned_docs/version-v3.x/guide/validation.md b/versioned_docs/version-v3.x/guide/validation.md deleted file mode 100644 index 450255264d5..00000000000 --- a/versioned_docs/version-v3.x/guide/validation.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -id: validation -title: πŸ”Ž Validation -sidebar_position: 5 ---- - -## Validator package - -Fiber provides the [Bind](../api/bind.md#validation) function to validate and bind [request data](../api/bind.md#binders) to a struct. - -```go title="Example" - -import "github.com/go-playground/validator/v10" - -type structValidator struct { - validate *validator.Validate -} - -// Validator needs to implement the Validate method -func (v *structValidator) Validate(out any) error { - return v.validate.Struct(out) -} - -// Setup your validator in the config -app := fiber.New(fiber.Config{ - StructValidator: &structValidator{validate: validator.New()}, -}) - -type User struct { - Name string `json:"name" form:"name" query:"name" validate:"required"` - Age int `json:"age" form:"age" query:"age" validate:"gte=0,lte=100"` -} - -app.Post("/", func(c fiber.Ctx) error { - user := new(User) - - // Works with all bind methods - Body, Query, Form, ... - if err := c.Bind().Body(user); err != nil { // <- here you receive the validation errors - return err - } - - return c.JSON(user) -}) -``` diff --git a/versioned_docs/version-v3.x/intro.md b/versioned_docs/version-v3.x/intro.md deleted file mode 100644 index 9c651b38d6b..00000000000 --- a/versioned_docs/version-v3.x/intro.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -slug: / -id: welcome -title: πŸ‘‹ Welcome -sidebar_position: 1 ---- -An online API documentation with examples so you can start building web apps with Fiber right away! - -**Fiber** is an [Express](https://github.com/expressjs/express) inspired **web framework** built on top of [Fasthttp](https://github.com/valyala/fasthttp), the **fastest** HTTP engine for [Go](https://go.dev/doc/). Designed to **ease** things up for **fast** development with **zero memory allocation** and **performance** in mind. - -These docs are for **Fiber v3**, which was released on **March XX, 2024**. - -### Installation - -First of all, [download](https://go.dev/dl/) and install Go. `1.21` or higher is required. - -Installation is done using the [`go get`](https://pkg.go.dev/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) command: - -```bash -go get github.com/gofiber/fiber/v3 -``` - -### Zero Allocation - -Fiber is optimized for **high-performance**, meaning values returned from **fiber.Ctx** are **not** immutable by default and **will** be re-used across requests. As a rule of thumb, you **must** only use context values within the handler and **must not** keep any references. Once you return from the handler, any values obtained from the context will be re-used in future requests. Here is an example: - -```go -func handler(c fiber.Ctx) error { - // Variable is only valid within this handler - result := c.Params("foo") - - // ... -} -``` - -If you need to persist such values outside the handler, make copies of their **underlying buffer** using the [copy](https://pkg.go.dev/builtin/#copy) builtin. Here is an example for persisting a string: - -```go -func handler(c fiber.Ctx) error { - // Variable is only valid within this handler - result := c.Params("foo") - - // Make a copy - buffer := make([]byte, len(result)) - copy(buffer, result) - resultCopy := string(buffer) - // Variable is now valid forever - - // ... -} -``` - -We created a custom `CopyString` function that does the above and is available under [gofiber/utils](https://github.com/gofiber/utils). - -```go -app.Get("/:foo", func(c fiber.Ctx) error { - // Variable is now immutable - result := utils.CopyString(c.Params("foo")) - - // ... -}) -``` - -Alternatively, you can also use the `Immutable` setting. It will make all values returned from the context immutable, allowing you to persist them anywhere. Of course, this comes at the cost of performance. - -```go -app := fiber.New(fiber.Config{ - Immutable: true, -}) -``` - -For more information, please check [**\#426**](https://github.com/gofiber/fiber/issues/426), [**\#185**](https://github.com/gofiber/fiber/issues/185) and [**\#3012**](https://github.com/gofiber/fiber/issues/3012). - -### Hello, World! - -Embedded below is essentially the most straightforward **Fiber** app you can create: - -```go -package main - -import "github.com/gofiber/fiber/v3" - -func main() { - app := fiber.New() - - app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") - }) - - app.Listen(":3000") -} -``` - -```bash -go run server.go -``` - -Browse to `http://localhost:3000` and you should see `Hello, World!` on the page. - -### Basic routing - -Routing refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (`GET`, `PUT`, `POST`, etc.). - -Each route can have **multiple handler functions** that are executed when the route is matched. - -Route definition takes the following structures: - -```go -// Function signature -app.Method(path string, ...func(fiber.Ctx) error) -``` - -- `app` is an instance of **Fiber** -- `Method` is an [HTTP request method](https://docs.gofiber.io/api/app#route-handlers): `GET`, `PUT`, `POST`, etc. -- `path` is a virtual path on the server -- `func(fiber.Ctx) error` is a callback function containing the [Context](https://docs.gofiber.io/api/ctx) executed when the route is matched - -**Simple route** - -```go -// Respond with "Hello, World!" on root path, "/" -app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") -}) -``` - -**Parameters** - -```go -// GET http://localhost:8080/hello%20world - -app.Get("/:value", func(c fiber.Ctx) error { - return c.SendString("value: " + c.Params("value")) - // => Get request with value: hello world -}) -``` - -**Optional parameter** - -```go -// GET http://localhost:3000/john - -app.Get("/:name?", func(c fiber.Ctx) error { - if c.Params("name") != "" { - return c.SendString("Hello " + c.Params("name")) - // => Hello john - } - return c.SendString("Where is john?") -}) -``` - -**Wildcards** - -```go -// GET http://localhost:3000/api/user/john - -app.Get("/api/*", func(c fiber.Ctx) error { - return c.SendString("API path: " + c.Params("*")) - // => API path: user/john -}) -``` - -### Static files - -To serve static files such as **images**, **CSS**, and **JavaScript** files, replace your function handler with a file or directory string. -You can check out [static middleware](./middleware/static.md) for more information. -Function signature: - -Use the following code to serve files in a directory named `./public`: - -```go -app := fiber.New() - -app.Get("/*", static.New("./public")) - -app.Listen(":3000") -``` - -Now, you can load the files that are in the `./public` directory: - -```bash -http://localhost:3000/hello.html -http://localhost:3000/js/jquery.js -http://localhost:3000/css/style.css -``` - -### Note - -For more information on how to build APIs in Go with Fiber, please check out this excellent article -[on building an express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/). diff --git a/versioned_docs/version-v3.x/middleware/_category_.json b/versioned_docs/version-v3.x/middleware/_category_.json deleted file mode 100644 index 625fd1b39b0..00000000000 --- a/versioned_docs/version-v3.x/middleware/_category_.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "label": "\uD83E\uDDEC Middleware", - "position": 4, - "collapsed": true, - "link": { - "type": "generated-index", - "description": "Middleware is a function chained in the HTTP request cycle with access to the Context which it uses to perform a specific action, for example, logging every request or enabling CORS." - } -} diff --git a/versioned_docs/version-v3.x/middleware/adaptor.md b/versioned_docs/version-v3.x/middleware/adaptor.md deleted file mode 100644 index 39fc1895aff..00000000000 --- a/versioned_docs/version-v3.x/middleware/adaptor.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -id: adaptor ---- - -# Adaptor - -Converter for net/http handlers to/from Fiber request handlers, special thanks to [@arsmn](https://github.com/arsmn)! - -## Signatures -| Name | Signature | Description -| :--- | :--- | :--- -| HTTPHandler | `HTTPHandler(h http.Handler) fiber.Handler` | http.Handler -> fiber.Handler -| HTTPHandlerFunc | `HTTPHandlerFunc(h http.HandlerFunc) fiber.Handler` | http.HandlerFunc -> fiber.Handler -| HTTPMiddleware | `HTTPHandlerFunc(mw func(http.Handler) http.Handler) fiber.Handler` | func(http.Handler) http.Handler -> fiber.Handler -| FiberHandler | `FiberHandler(h fiber.Handler) http.Handler` | fiber.Handler -> http.Handler -| FiberHandlerFunc | `FiberHandlerFunc(h fiber.Handler) http.HandlerFunc` | fiber.Handler -> http.HandlerFunc -| FiberApp | `FiberApp(app *fiber.App) http.HandlerFunc` | Fiber app -> http.HandlerFunc -| ConvertRequest | `ConvertRequest(c fiber.Ctx, forServer bool) (*http.Request, error)` | fiber.Ctx -> http.Request -| CopyContextToFiberContext | `CopyContextToFiberContext(context any, requestContext *fasthttp.RequestCtx)` | context.Context -> fasthttp.RequestCtx - -## Examples - -### net/http to Fiber -```go -package main - -import ( - "fmt" - "net/http" - - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/adaptor" -) - -func main() { - // New fiber app - app := fiber.New() - - // http.Handler -> fiber.Handler - app.Get("/", adaptor.HTTPHandler(handler(greet))) - - // http.HandlerFunc -> fiber.Handler - app.Get("/func", adaptor.HTTPHandlerFunc(greet)) - - // Listen on port 3000 - app.Listen(":3000") -} - -func handler(f http.HandlerFunc) http.Handler { - return http.HandlerFunc(f) -} - -func greet(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, "Hello World!") -} -``` - -### net/http middleware to Fiber -```go -package main - -import ( - "log" - "net/http" - - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/adaptor" -) - -func main() { - // New fiber app - app := fiber.New() - - // http middleware -> fiber.Handler - app.Use(adaptor.HTTPMiddleware(logMiddleware)) - - // Listen on port 3000 - app.Listen(":3000") -} - -func logMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - log.Println("log middleware") - next.ServeHTTP(w, r) - }) -} -``` - -### Fiber Handler to net/http -```go -package main - -import ( - "net/http" - - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/adaptor" -) - -func main() { - // fiber.Handler -> http.Handler - http.Handle("/", adaptor.FiberHandler(greet)) - - // fiber.Handler -> http.HandlerFunc - http.HandleFunc("/func", adaptor.FiberHandlerFunc(greet)) - - // Listen on port 3000 - http.ListenAndServe(":3000", nil) -} - -func greet(c fiber.Ctx) error { - return c.SendString("Hello World!") -} -``` - -### Fiber App to net/http -```go -package main - -import ( - "net/http" - - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/adaptor" -) - -func main() { - app := fiber.New() - - app.Get("/greet", greet) - - // Listen on port 3000 - http.ListenAndServe(":3000", adaptor.FiberApp(app)) -} - -func greet(c fiber.Ctx) error { - return c.SendString("Hello World!") -} -``` - -### Fiber Context to (net/http).Request -```go -package main - -import ( - "net/http" - - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/adaptor" -) - -func main() { - app := fiber.New() - - app.Get("/greet", greetWithHTTPReq) - - // Listen on port 3000 - http.ListenAndServe(":3000", adaptor.FiberApp(app)) -} - -func greetWithHTTPReq(c fiber.Ctx) error { - httpReq, err := adaptor.ConvertRequest(c, false) - if err != nil { - return err - } - - return c.SendString("Request URL: " + httpReq.URL.String()) -} -``` diff --git a/versioned_docs/version-v3.x/middleware/basicauth.md b/versioned_docs/version-v3.x/middleware/basicauth.md deleted file mode 100644 index 246945ce7b7..00000000000 --- a/versioned_docs/version-v3.x/middleware/basicauth.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -id: basicauth ---- - -# BasicAuth - -Basic Authentication middleware for [Fiber](https://github.com/gofiber/fiber) that provides an HTTP basic authentication. It calls the next handler for valid credentials and [401 Unauthorized](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401) or a custom response for missing or invalid credentials. - -## Signatures - -```go -func New(config Config) fiber.Handler -func UsernameFromContext(c fiber.Ctx) string -func PasswordFromContext(c fiber.Ctx) string -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/basicauth" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Provide a minimal config -app.Use(basicauth.New(basicauth.Config{ - Users: map[string]string{ - "john": "doe", - "admin": "123456", - }, -})) - -// Or extend your config for customization -app.Use(basicauth.New(basicauth.Config{ - Users: map[string]string{ - "john": "doe", - "admin": "123456", - }, - Realm: "Forbidden", - Authorizer: func(user, pass string) bool { - if user == "john" && pass == "doe" { - return true - } - if user == "admin" && pass == "123456" { - return true - } - return false - }, - Unauthorized: func(c fiber.Ctx) error { - return c.SendFile("./unauthorized.html") - }, -})) -``` - -Getting the username and password - -```go -func handler(c fiber.Ctx) error { - username := basicauth.UsernameFromContext(c) - password := basicauth.PasswordFromContext(c) - log.Printf("Username: %s Password: %s", username, password) - return c.SendString("Hello, " + username) -} -``` - -## Config - -| Property | Type | Description | Default | -|:----------------|:----------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Users | `map[string]string` | Users defines the allowed credentials. | `map[string]string{}` | -| Realm | `string` | Realm is a string to define the realm attribute of BasicAuth. The realm identifies the system to authenticate against and can be used by clients to save credentials. | `"Restricted"` | -| Authorizer | `func(string, string) bool` | Authorizer defines a function to check the credentials. It will be called with a username and password and is expected to return true or false to indicate approval. | `nil` | -| Unauthorized | `fiber.Handler` | Unauthorized defines the response body for unauthorized responses. | `nil` | - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, - Users: map[string]string{}, - Realm: "Restricted", - Authorizer: nil, - Unauthorized: nil, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/cache.md b/versioned_docs/version-v3.x/middleware/cache.md deleted file mode 100644 index f62ab9ff253..00000000000 --- a/versioned_docs/version-v3.x/middleware/cache.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: cache ---- - -# Cache - -Cache middleware for [Fiber](https://github.com/gofiber/fiber) designed to intercept responses and cache them. This middleware will cache the `Body`, `Content-Type` and `StatusCode` using the `c.Path()` as unique identifier. Special thanks to [@codemicro](https://github.com/codemicro/fiber-cache) for creating this middleware for Fiber core! - -Request Directives
-`Cache-Control: no-cache` will return the up-to-date response but still caches it. You will always get a `miss` cache status.
-`Cache-Control: no-store` will refrain from caching. You will always get the up-to-date response. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/cache" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use(cache.New()) - -// Or extend your config for customization -app.Use(cache.New(cache.Config{ - Next: func(c fiber.Ctx) bool { - return fiber.Query[bool](c, "noCache") - }, - Expiration: 30 * time.Minute, - CacheControl: true, -})) -``` - -Or you can custom key and expire time like this: - -```go -app.Use(cache.New(cache.Config{ - ExpirationGenerator: func(c fiber.Ctx, cfg *cache.Config) time.Duration { - newCacheTime, _ := strconv.Atoi(c.GetRespHeader("Cache-Time", "600")) - return time.Second * time.Duration(newCacheTime) - }, - KeyGenerator: func(c fiber.Ctx) string { - return utils.CopyString(c.Path()) - }, -})) - -app.Get("/", func(c fiber.Ctx) error { - c.Response().Header.Add("Cache-Time", "6000") - return c.SendString("hi") -}) -``` - -You can also invalidate the cache by using the `CacheInvalidator` function as shown below: - -```go -app.Use(cache.New(cache.Config{ - CacheInvalidator: func(c fiber.Ctx) bool { - return fiber.Query[bool](c, "invalidateCache") - }, -})) -``` - -The `CacheInvalidator` function allows you to define custom conditions for cache invalidation. Return true if conditions such as specific query parameters or headers are met, which require the cache to be invalidated. For example, in this code, the cache is invalidated when the query parameter invalidateCache is set to true. - -## Config - -| Property | Type | Description | Default | -| :------------------- | :--------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------- | -| Next | `func(fiber.Ctx) bool` | Next defines a function that is executed before creating the cache entry and can be used to execute the request without cache creation. If an entry already exists, it will be used. If you want to completely bypass the cache functionality in certain cases, you should use the [skip middleware](skip.md). | `nil` | -| Expiration | `time.Duration` | Expiration is the time that a cached response will live. | `1 * time.Minute` | -| CacheHeader | `string` | CacheHeader is the header on the response header that indicates the cache status, with the possible return values "hit," "miss," or "unreachable." | `X-Cache` | -| CacheControl | `bool` | CacheControl enables client-side caching if set to true. | `false` | -| CacheInvalidator | `func(fiber.Ctx) bool` | CacheInvalidator defines a function that is executed before checking the cache entry. It can be used to invalidate the existing cache manually by returning true. | `nil` | -| KeyGenerator | `func(fiber.Ctx) string` | Key allows you to generate custom keys. | `func(c fiber.Ctx) string { return utils.CopyString(c.Path()) }` | -| ExpirationGenerator | `func(fiber.Ctx, *cache.Config) time.Duration` | ExpirationGenerator allows you to generate custom expiration keys based on the request. | `nil` | -| Storage | `fiber.Storage` | Store is used to store the state of the middleware. | In-memory store | -| Store (Deprecated) | `fiber.Storage` | Deprecated: Use Storage instead. | In-memory store | -| Key (Deprecated) | `func(fiber.Ctx) string` | Deprecated: Use KeyGenerator instead. | `nil` | -| StoreResponseHeaders | `bool` | StoreResponseHeaders allows you to store additional headers generated by next middlewares & handler. | `false` | -| MaxBytes | `uint` | MaxBytes is the maximum number of bytes of response bodies simultaneously stored in cache. | `0` (No limit) | -| Methods | `[]string` | Methods specifies the HTTP methods to cache. | `[]string{fiber.MethodGet, fiber.MethodHead}` | - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, - Expiration: 1 * time.Minute, - CacheHeader: "X-Cache", - CacheControl: false, - CacheInvalidator: nil, - KeyGenerator: func(c fiber.Ctx) string { - return utils.CopyString(c.Path()) - }, - ExpirationGenerator: nil, - StoreResponseHeaders: false, - Storage: nil, - MaxBytes: 0, - Methods: []string{fiber.MethodGet, fiber.MethodHead}, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/compress.md b/versioned_docs/version-v3.x/middleware/compress.md deleted file mode 100644 index 5a119ce2013..00000000000 --- a/versioned_docs/version-v3.x/middleware/compress.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -id: compress ---- - -# Compress - -Compression middleware for [Fiber](https://github.com/gofiber/fiber) that will compress the response using `gzip`, `deflate`, `brotli`, and `zstd` compression depending on the [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header. - -:::note -The compression middleware refrains from compressing bodies that are smaller than 200 bytes. This decision is based on the observation that, in such cases, the compressed size is likely to exceed the original size, making compression inefficient. [more](https://github.com/valyala/fasthttp/blob/497922a21ef4b314f393887e9c6147b8c3e3eda4/http.go#L1713-L1715) -::: - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/compress" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use(compress.New()) - -// Or extend your config for customization -app.Use(compress.New(compress.Config{ - Level: compress.LevelBestSpeed, // 1 -})) - -// Skip middleware for specific routes -app.Use(compress.New(compress.Config{ - Next: func(c fiber.Ctx) bool { - return c.Path() == "/dont_compress" - }, - Level: compress.LevelBestSpeed, // 1 -})) -``` - -## Config - -### Config - -| Property | Type | Description | Default | -|:---------|:------------------------|:--------------------------------------------------------------------|:-------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Level | `Level` | Level determines the compression algorithm. | `LevelDefault (0)` | - -Possible values for the "Level" field are: - -- `LevelDisabled (-1)`: Compression is disabled. -- `LevelDefault (0)`: Default compression level. -- `LevelBestSpeed (1)`: Best compression speed. -- `LevelBestCompression (2)`: Best compression. - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, - Level: LevelDefault, -} -``` - -## Constants - -```go -// Compression levels -const ( - LevelDisabled = -1 - LevelDefault = 0 - LevelBestSpeed = 1 - LevelBestCompression = 2 -) -``` diff --git a/versioned_docs/version-v3.x/middleware/cors.md b/versioned_docs/version-v3.x/middleware/cors.md deleted file mode 100644 index 4442d4b43fd..00000000000 --- a/versioned_docs/version-v3.x/middleware/cors.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -id: cors ---- - -# CORS - -CORS (Cross-Origin Resource Sharing) is a middleware for [Fiber](https://github.com/gofiber/fiber) that allows servers to specify who can access its resources and how. It's not a security feature, but a way to relax the security model of web browsers for cross-origin requests. You can learn more about CORS on [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). - -This middleware works by adding CORS headers to responses from your Fiber application. These headers specify which origins, methods, and headers are allowed for cross-origin requests. It also handles preflight requests, which are a CORS mechanism to check if the actual request is safe to send. - -The middleware uses the `AllowOrigins` option to control which origins can make cross-origin requests. It supports single origin, multiple origins, subdomain matching, and wildcard origin. It also allows programmatic origin validation with the `AllowOriginsFunc` option. - -To ensure that the provided `AllowOrigins` origins are correctly formatted, this middleware validates and normalizes them. It checks for valid schemes, i.e., HTTP or HTTPS, and it will automatically remove trailing slashes. If the provided origin is invalid, the middleware will panic. - -When configuring CORS, it's important to avoid [common pitfalls](#common-pitfalls) like using a wildcard origin with credentials, being overly permissive with origins, and inadequate validation with `AllowOriginsFunc`. Misconfiguration can expose your application to various security risks. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/cors" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -### Basic usage - -To use the default configuration, simply use `cors.New()`. This will allow wildcard origins '*', all methods, no credentials, and no headers or exposed headers. - -```go -app.Use(cors.New()) -``` - -### Custom configuration (specific origins, headers, etc.) - -```go -// Initialize default config -app.Use(cors.New()) - -// Or extend your config for customization -app.Use(cors.New(cors.Config{ - AllowOrigins: "https://gofiber.io, https://gofiber.net", - AllowHeaders: "Origin, Content-Type, Accept", -})) -``` - -### Dynamic origin validation - -You can use `AllowOriginsFunc` to programmatically determine whether to allow a request based on its origin. This is useful when you need to validate origins against a database or other dynamic sources. The function should return `true` if the origin is allowed, and `false` otherwise. - -Be sure to review the [security considerations](#security-considerations) when using `AllowOriginsFunc`. - -:::caution -Never allow `AllowOriginsFunc` to return `true` for all origins. This is particularly crucial when `AllowCredentials` is set to `true`. Doing so can bypass the restriction of using a wildcard origin with credentials, exposing your application to serious security threats. - -If you need to allow wildcard origins, use `AllowOrigins` with a wildcard `"*"` instead of `AllowOriginsFunc`. -::: - -```go -// dbCheckOrigin checks if the origin is in the list of allowed origins in the database. -func dbCheckOrigin(db *sql.DB, origin string) bool { - // Placeholder query - adjust according to your database schema and query needs - query := "SELECT COUNT(*) FROM allowed_origins WHERE origin = $1" - - var count int - err := db.QueryRow(query, origin).Scan(&count) - if err != nil { - // Handle error (e.g., log it); for simplicity, we return false here - return false - } - - return count > 0 -} - -// ... - -app.Use(cors.New(cors.Config{ - AllowOriginsFunc: func(origin string) bool { - return dbCheckOrigin(db, origin) - }, -})) -``` - -### Prohibited usage - -The following example is prohibited because it can expose your application to security risks. It sets `AllowOrigins` to `"*"` (a wildcard) and `AllowCredentials` to `true`. - -```go -app.Use(cors.New(cors.Config{ - AllowOrigins: []string{"*"}, - AllowCredentials: true, -})) -``` - -This will result in the following panic: - -``` -panic: [CORS] Configuration error: When 'AllowCredentials' is set to true, 'AllowOrigins' cannot contain a wildcard origin '*'. Please specify allowed origins explicitly or adjust 'AllowCredentials' setting. -``` - -## Config - -| Property | Type | Description | Default | -|:---------------------|:----------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------| -| AllowCredentials | `bool` | AllowCredentials indicates whether or not the response to the request can be exposed when the credentials flag is true. When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. Note: If true, AllowOrigins cannot be set to a wildcard (`"*"`) to prevent security vulnerabilities. | `false` | -| AllowHeaders | `[]string` | AllowHeaders defines a list of request headers that can be used when making the actual request. This is in response to a preflight request. | `[]` | -| AllowMethods | `[]string` | AllowMethods defines a list of methods allowed when accessing the resource. This is used in response to a preflight request. | `"GET, POST, HEAD, PUT, DELETE, PATCH"` | -| AllowOrigins | `[]string` | AllowOrigins defines a list of origins that may access the resource. This supports subdomain matching, so you can use a value like "https://*.example.com" to allow any subdomain of example.com to submit requests. If the special wildcard `"*"` is present in the list, all origins will be allowed. | `["*"]` | -| AllowOriginsFunc | `func(origin string) bool` | `AllowOriginsFunc` is a function that dynamically determines whether to allow a request based on its origin. If this function returns `true`, the 'Access-Control-Allow-Origin' response header will be set to the request's 'origin' header. This function is only used if the request's origin doesn't match any origin in `AllowOrigins`. | `nil` | -| AllowPrivateNetwork | `bool` | Indicates whether the `Access-Control-Allow-Private-Network` response header should be set to `true`, allowing requests from private networks. This aligns with modern security practices for web applications interacting with private networks. | `false` | -| ExposeHeaders | `string` | ExposeHeaders defines whitelist headers that clients are allowed to access. | `[]` | -| MaxAge | `int` | MaxAge indicates how long (in seconds) the results of a preflight request can be cached. If you pass MaxAge 0, the Access-Control-Max-Age header will not be added and the browser will use 5 seconds by default. To disable caching completely, pass MaxAge value negative. It will set the Access-Control-Max-Age header to 0. | `0` | -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | - -:::note -If AllowOrigins is a zero value `[]string{}`, and AllowOriginsFunc is provided, the middleware will not default to allowing all origins with the wildcard value "*". Instead, it will rely on the AllowOriginsFunc to dynamically determine whether to allow a request based on its origin. This provides more flexibility and control over which origins are allowed. -::: - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, - AllowOriginsFunc: nil, - AllowOrigins: []string{"*"}, - AllowMethods: []string{ - fiber.MethodGet, - fiber.MethodPost, - fiber.MethodHead, - fiber.MethodPut, - fiber.MethodDelete, - fiber.MethodPatch, - }, - AllowHeaders: []string{}, - AllowCredentials: false, - ExposeHeaders: []string{}, - MaxAge: 0, - AllowPrivateNetwork: false, -} -``` - -## Subdomain Matching - -The `AllowOrigins` configuration supports matching subdomains at any level. This means you can use a value like `"https://*.example.com"` to allow any subdomain of `example.com` to submit requests, including multiple subdomain levels such as `"https://sub.sub.example.com"`. - -### Example - -If you want to allow CORS requests from any subdomain of `example.com`, including nested subdomains, you can configure the `AllowOrigins` like so: - -```go -app.Use(cors.New(cors.Config{ - AllowOrigins: "https://*.example.com", -})) -``` - -# How It Works - -The CORS middleware works by adding the necessary CORS headers to responses from your Fiber application. These headers tell browsers what origins, methods, and headers are allowed for cross-origin requests. - -When a request comes in, the middleware first checks if it's a preflight request, which is a CORS mechanism to determine whether the actual request is safe to send. Preflight requests are HTTP OPTIONS requests with specific CORS headers. If it's a preflight request, the middleware responds with the appropriate CORS headers and ends the request. - -If it's not a preflight request, the middleware adds the CORS headers to the response and passes the request to the next handler. The actual CORS headers added depend on the configuration of the middleware. - -The `AllowOrigins` option controls which origins can make cross-origin requests. The middleware handles different `AllowOrigins` configurations as follows: - -- **Single origin:** If `AllowOrigins` is set to a single origin like `"http://www.example.com"`, and that origin matches the origin of the incoming request, the middleware adds the header `Access-Control-Allow-Origin: http://www.example.com` to the response. - -- **Multiple origins:** If `AllowOrigins` is set to multiple origins like `"https://example.com, https://www.example.com"`, the middleware picks the origin that matches the origin of the incoming request. - -- **Subdomain matching:** If `AllowOrigins` includes `"https://*.example.com"`, a subdomain like `https://sub.example.com` will be matched and `"https://sub.example.com"` will be the header. This will also match `https://sub.sub.example.com` and so on, but not `https://example.com`. - -- **Wildcard origin:** If `AllowOrigins` is set to `"*"`, the middleware uses that and adds the header `Access-Control-Allow-Origin: *` to the response. - -In all cases above, except the **Wildcard origin**, the middleware will either add the `Access-Control-Allow-Origin` header to the response matching the origin of the incoming request, or it will not add the header at all if the origin is not allowed. - -- **Programmatic origin validation:**: The middleware also handles the `AllowOriginsFunc` option, which allows you to programmatically determine if an origin is allowed. If `AllowOriginsFunc` returns `true` for an origin, the middleware sets the `Access-Control-Allow-Origin` header to that origin. - -The `AllowMethods` option controls which HTTP methods are allowed. For example, if `AllowMethods` is set to `"GET, POST"`, the middleware adds the header `Access-Control-Allow-Methods: GET, POST` to the response. - -The `AllowHeaders` option specifies which headers are allowed in the actual request. The middleware sets the Access-Control-Allow-Headers response header to the value of `AllowHeaders`. This informs the client which headers it can use in the actual request. - -The `AllowCredentials` option indicates whether the response to the request can be exposed when the credentials flag is true. If `AllowCredentials` is set to `true`, the middleware adds the header `Access-Control-Allow-Credentials: true` to the response. To prevent security vulnerabilities, `AllowCredentials` cannot be set to `true` if `AllowOrigins` is set to a wildcard (`*`). - -The `ExposeHeaders` option defines a whitelist of headers that clients are allowed to access. If `ExposeHeaders` is set to `"X-Custom-Header"`, the middleware adds the header `Access-Control-Expose-Headers: X-Custom-Header` to the response. - -The `MaxAge` option indicates how long the results of a preflight request can be cached. If `MaxAge` is set to `3600`, the middleware adds the header `Access-Control-Max-Age: 3600` to the response. - -The `Vary` header is used in this middleware to inform the client that the server's response to a request. For or both preflight and actual requests, the Vary header is set to `Access-Control-Request-Method` and `Access-Control-Request-Headers`. For preflight requests, the Vary header is also set to `Origin`. The `Vary` header is important for caching. It helps caches (like a web browser's cache or a CDN) determine when a cached response can be used in response to a future request, and when the server needs to be queried for a new response. - -## Security Considerations - -When configuring CORS, misconfiguration can potentially expose your application to various security risks. Here are some secure configurations and common pitfalls to avoid: - -### Secure Configurations - -- **Specify Allowed Origins**: Instead of using a wildcard (`"*"`), specify the exact domains allowed to make requests. For example, `AllowOrigins: "https://www.example.com, https://api.example.com"` ensures only these domains can make cross-origin requests to your application. - -- **Use Credentials Carefully**: If your application needs to support credentials in cross-origin requests, ensure `AllowCredentials` is set to `true` and specify exact origins in `AllowOrigins`. Do not use a wildcard origin in this case. - -- **Limit Exposed Headers**: Only whitelist headers that are necessary for the client-side application by setting `ExposeHeaders` appropriately. This minimizes the risk of exposing sensitive information. - -### Common Pitfalls - -- **Wildcard Origin with Credentials**: Setting `AllowOrigins` to `"*"` (a wildcard) and `AllowCredentials` to `true` is a common misconfiguration. This combination is prohibited because it can expose your application to security risks. - -- **Overly Permissive Origins**: Specifying too many origins or using overly broad patterns (e.g., `https://*.example.com`) can inadvertently allow malicious sites to interact with your application. Be as specific as possible with allowed origins. - -- **Inadequate `AllowOriginsFunc` Validation**: When using `AllowOriginsFunc` for dynamic origin validation, ensure the function includes robust checks to prevent unauthorized origins from being accepted. Overly permissive validation can lead to security vulnerabilities. Never allow `AllowOriginsFunc` to return `true` for all origins. This is particularly crucial when `AllowCredentials` is set to `true`. Doing so can bypass the restriction of using a wildcard origin with credentials, exposing your application to serious security threats. If you need to allow wildcard origins, use `AllowOrigins` with a wildcard `"*"` instead of `AllowOriginsFunc`. - -Remember, the key to secure CORS configuration is specificity and caution. By carefully selecting which origins, methods, and headers are allowed, you can help protect your application from cross-origin attacks. diff --git a/versioned_docs/version-v3.x/middleware/csrf.md b/versioned_docs/version-v3.x/middleware/csrf.md deleted file mode 100644 index 739802501cb..00000000000 --- a/versioned_docs/version-v3.x/middleware/csrf.md +++ /dev/null @@ -1,337 +0,0 @@ ---- -id: csrf ---- - -# CSRF - -The CSRF middleware for [Fiber](https://github.com/gofiber/fiber) provides protection against [Cross-Site Request Forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery) (CSRF) attacks. Requests made using methods other than those defined as 'safe' by [RFC9110#section-9.2.1](https://datatracker.ietf.org/doc/html/rfc9110.html#section-9.2.1) (GET, HEAD, OPTIONS, and TRACE) are validated using tokens. If a potential attack is detected, the middleware will return a default 403 Forbidden error. - -This middleware offers two [Token Validation Patterns](#token-validation-patterns): the [Double Submit Cookie Pattern (default)](#double-submit-cookie-pattern-default), and the [Synchronizer Token Pattern (with Session)](#synchronizer-token-pattern-with-session). - -As a [Defense In Depth](#defense-in-depth) measure, this middleware performs [Referer Checking](#referer-checking) for HTTPS requests. - -## How to use Fiber's CSRF Middleware - -## Examples - -Import the middleware package that is part of the Fiber web framework: - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/csrf" -) -``` - -After initializing your Fiber app, you can use the following code to initialize the middleware: - -```go -// Initialize default config -app.Use(csrf.New()) - -// Or extend your config for customization -app.Use(csrf.New(csrf.Config{ - KeyLookup: "header:X-Csrf-Token", - CookieName: "csrf_", - CookieSameSite: "Lax", - Expiration: 1 * time.Hour, - KeyGenerator: utils.UUIDv4, - Extractor: func(c fiber.Ctx) (string, error) { ... }, -})) -``` - -:::info -KeyLookup will be ignored if Extractor is explicitly set. -::: - -Getting the CSRF token in a handler: - -```go -func handler(c fiber.Ctx) error { - handler := csrf.HandlerFromContext(c) - token := csrf.TokenFromContext(c) - if handler == nil { - panic("csrf middleware handler not registered") - } - cfg := handler.Config - if cfg == nil { - panic("csrf middleware handler has no config") - } - if !strings.Contains(cfg.KeyLookup, ":") { - panic("invalid KeyLookup format") - } - formKey := strings.Split(cfg.KeyLookup, ":")[1] - - tmpl := fmt.Sprintf(`
- - - -
`, formKey, token) - c.Set("Content-Type", "text/html") - return c.SendString(tmpl) -} -``` - -## Recipes for Common Use Cases - -There are two basic use cases for the CSRF middleware: - -1. **Without Sessions**: This is the simplest way to use the middleware. It uses the Double Submit Cookie Pattern and does not require a user session. - - - See GoFiber recipe [CSRF](https://github.com/gofiber/recipes/tree/master/csrf) for an example of using the CSRF middleware without a user session. - -2. **With Sessions**: This is generally considered more secure. It uses the Synchronizer Token Pattern and requires a user session, and the use of pre-session, which prevents login CSRF attacks. - - - See GoFiber recipe [CSRF with Session](https://github.com/gofiber/recipes/tree/master/csrf-with-session) for an example of using the CSRF middleware with a user session. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -func TokenFromContext(c fiber.Ctx) string -func HandlerFromContext(c fiber.Ctx) *Handler - -func (h *Handler) DeleteToken(c fiber.Ctx) error -``` - - -## Config - -| Property | Type | Description | Default | -|:------------------|:-----------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| KeyLookup | `string` | KeyLookup is a string in the form of "`:`" that is used to create an Extractor that extracts the token from the request. Possible values: "`header:`", "`query:`", "`param:`", "`form:`", "`cookie:`". Ignored if an Extractor is explicitly set. | "header:X-CSRF-Token" | -| CookieName | `string` | Name of the csrf cookie. This cookie will store the csrf key. | "csrf_" | -| CookieDomain | `string` | Domain of the CSRF cookie. | "" | -| CookiePath | `string` | Path of the CSRF cookie. | "" | -| CookieSecure | `bool` | Indicates if the CSRF cookie is secure. | false | -| CookieHTTPOnly | `bool` | Indicates if the CSRF cookie is HTTP-only. | false | -| CookieSameSite | `string` | Value of SameSite cookie. | "Lax" | -| CookieSessionOnly | `bool` | Decides whether the cookie should last for only the browser session. Ignores Expiration if set to true. | false | -| Expiration | `time.Duration` | Expiration is the duration before the CSRF token will expire. | 1 * time.Hour | -| KeyGenerator | `func() string` | KeyGenerator creates a new CSRF token. | utils.UUID | -| ErrorHandler | `fiber.ErrorHandler` | ErrorHandler is executed when an error is returned from fiber.Handler. | DefaultErrorHandler | -| Extractor | `func(fiber.Ctx) (string, error)` | Extractor returns the CSRF token. If set, this will be used in place of an Extractor based on KeyLookup. | Extractor based on KeyLookup | -| SingleUseToken | `bool` | SingleUseToken indicates if the CSRF token be destroyed and a new one generated on each use. (See TokenLifecycle) | false | -| Storage | `fiber.Storage` | Store is used to store the state of the middleware. | `nil` | -| Session | `*session.Store` | Session is used to store the state of the middleware. Overrides Storage if set. | `nil` | -| SessionKey | `string` | SessionKey is the key used to store the token in the session. | "csrfToken" | -| TrustedOrigins | `[]string` | TrustedOrigins is a list of trusted origins for unsafe requests. This supports subdomain matching, so you can use a value like "https://*.example.com" to allow any subdomain of example.com to submit requests. | `[]` | - -### Default Config - -```go -var ConfigDefault = Config{ - KeyLookup: "header:" + HeaderName, - CookieName: "csrf_", - CookieSameSite: "Lax", - Expiration: 1 * time.Hour, - KeyGenerator: utils.UUIDv4, - ErrorHandler: defaultErrorHandler, - Extractor: FromHeader(HeaderName), - SessionKey: "csrfToken", -} -``` - -### Recommended Config (with session) - -It's recommended to use this middleware with [fiber/middleware/session](https://docs.gofiber.io/api/middleware/session) to store the CSRF token within the session. This is generally more secure than the default configuration. - -```go -var ConfigDefault = Config{ - KeyLookup: "header:" + HeaderName, - CookieName: "__Host-csrf_", - CookieSameSite: "Lax", - CookieSecure: true, - CookieSessionOnly: true, - CookieHTTPOnly: true, - Expiration: 1 * time.Hour, - KeyGenerator: utils.UUIDv4, - ErrorHandler: defaultErrorHandler, - Extractor: FromHeader(HeaderName), - Session: session.Store, - SessionKey: "csrfToken", -} -``` - -### Trusted Origins - -The `TrustedOrigins` option is used to specify a list of trusted origins for unsafe requests. This is useful when you want to allow requests from other origins. This supports matching subdomains at any level. This means you can use a value like `"https://*.example.com"` to allow any subdomain of `example.com` to submit requests, including multiple subdomain levels such as `"https://sub.sub.example.com"`. - -To ensure that the provided `TrustedOrigins` origins are correctly formatted, this middleware validates and normalizes them. It checks for valid schemes, i.e., HTTP or HTTPS, and it will automatically remove trailing slashes. If the provided origin is invalid, the middleware will panic. - -#### Example with Explicit Origins - -In the following example, the CSRF middleware will allow requests from `trusted.example.com`, in addition to the current host. - -```go -app.Use(csrf.New(csrf.Config{ - TrustedOrigins: []string{"https://trusted.example.com"}, -})) -``` - -#### Example with Subdomain Matching - -In the following example, the CSRF middleware will allow requests from any subdomain of `example.com`, in addition to the current host. - -```go -app.Use(csrf.New(csrf.Config{ - TrustedOrigins: []string{"https://*.example.com"}, -})) -``` - -:::caution -When using `TrustedOrigins` with subdomain matching, make sure you control and trust all the subdomains, including all subdomain levels. If not, an attacker could create a subdomain under a trusted origin and use it to send harmful requests. -::: - -## Constants - -```go -const ( - HeaderName = "X-Csrf-Token" -) -``` - -## Sentinel Errors - -The CSRF middleware utilizes a set of sentinel errors to handle various scenarios and communicate errors effectively. These can be used within a [custom error handler](#custom-error-handler) to handle errors returned by the middleware. - -### Errors Returned to Error Handler - -- `ErrTokenNotFound`: Indicates that the CSRF token was not found. -- `ErrTokenInvalid`: Indicates that the CSRF token is invalid. -- `ErrRefererNotFound`: Indicates that the referer was not supplied. -- `ErrRefererInvalid`: Indicates that the referer is invalid. -- `ErrRefererNoMatch`: Indicates that the referer does not match host and is not a trusted origin. -- `ErrOriginInvalid`: Indicates that the origin is invalid. -- `ErrOriginNoMatch`: Indicates that the origin does not match host and is not a trusted origin. - -If you use the default error handler, the client will receive a 403 Forbidden error without any additional information. - -## Custom Error Handler - -You can use a custom error handler to handle errors returned by the CSRF middleware. The error handler is executed when an error is returned from the middleware. The error handler is passed the error returned from the middleware and the fiber.Ctx. - -Example, returning a JSON response for API requests and rendering an error page for other requests: - -```go -app.Use(csrf.New(csrf.Config{ - ErrorHandler: func(c fiber.Ctx, err error) error { - accepts := c.Accepts("html", "json") - path := c.Path() - if accepts == "json" || strings.HasPrefix(path, "/api/") { - return c.Status(fiber.StatusForbidden).JSON(fiber.Map{ - "error": "Forbidden", - }) - } - return c.Status(fiber.StatusForbidden).Render("error", fiber.Map{ - "Title": "Forbidden", - "Status": fiber.StatusForbidden, - }, "layouts/main") - }, -})) -``` - -## Custom Storage/Database - -You can use any storage from our [storage](https://github.com/gofiber/storage/) package. - -```go -storage := sqlite3.New() // From github.com/gofiber/storage/sqlite3 -app.Use(csrf.New(csrf.Config{ - Storage: storage, -})) -``` - -# How It Works - -## Token Generation - -CSRF tokens are generated on 'safe' requests and when the existing token has expired or hasn't been set yet. If `SingleUseToken` is `true`, a new token is generated after each use. Retrieve the CSRF token using `csrf.TokenFromContext(c)`. - -## Security Considerations - -This middleware is designed to protect against CSRF attacks but does not protect against other attack vectors, such as XSS. It should be used in combination with other security measures. - -:::danger -Never use 'safe' methods to mutate data, for example, never use a GET request to modify a resource. This middleware will not protect against CSRF attacks on 'safe' methods. -::: - -### Token Validation Patterns - -#### Double Submit Cookie Pattern (Default) - -By default, the middleware generates and stores tokens using the `fiber.Storage` interface. These tokens are not linked to any particular user session, and they are validated using the Double Submit Cookie pattern. The token is stored in a cookie, and then sent as a header on requests. The middleware compares the cookie value with the header value to validate the token. This is a secure pattern that does not require a user session. - -When the authorization status changes, the previously issued token MUST be deleted, and a new one generated. See [Token Lifecycle](#token-lifecycle) [Deleting Tokens](#deleting-tokens) for more information. - -:::caution -When using this pattern, it's important to set the `CookieSameSite` option to `Lax` or `Strict` and ensure that the Extractor is not `FromCookie`, and KeyLookup is not `cookie:`. -::: - -:::note -When using this pattern, this middleware uses our [Storage](https://github.com/gofiber/storage) package to support various databases through a single interface. The default configuration for Storage saves data to memory. See [Custom Storage/Database](#custom-storagedatabase) for customizing the storage. -::: - -#### Synchronizer Token Pattern (with Session) - -When using this middleware with a user session, the middleware can be configured to store the token within the session. This method is recommended when using a user session, as it is generally more secure than the Double Submit Cookie Pattern. - -When using this pattern it's important to regenerate the session when the authorization status changes, this will also delete the token. See: [Token Lifecycle](#token-lifecycle) for more information. - -:::caution -Pre-sessions are required and will be created automatically if not present. Use a session value to indicate authentication instead of relying on the presence of a session. -::: - -### Defense In Depth - -When using this middleware, it's recommended to serve your pages over HTTPS, set the `CookieSecure` option to `true`, and set the `CookieSameSite` option to `Lax` or `Strict`. This ensures that the cookie is only sent over HTTPS and not on requests from external sites. - -:::note -Cookie prefixes `__Host-` and `__Secure-` can be used to further secure the cookie. Note that these prefixes are not supported by all browsers and there are other limitations. See [MDN#Set-Cookie#cookie_prefixes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie_prefixes) for more information. - -To use these prefixes, set the `CookieName` option to `__Host-csrf_` or `__Secure-csrf_`. -::: - -### Referer Checking - -For HTTPS requests, this middleware performs strict referer checking. Even if a subdomain can set or modify cookies on your domain, it can't force a user to post to your application, since that request won't come from your own exact domain. - -:::caution -When HTTPS requests are protected by CSRF, referer checking is always carried out. - -The Referer header is automatically included in requests by all modern browsers, including those made using the JS Fetch API. However, if you're making use of this middleware with a custom client, it's important to ensure that the client sends a valid Referer header. -::: - -### Token Lifecycle - -Tokens are valid until they expire or until they are deleted. By default, tokens are valid for 1 hour, and each subsequent request extends the expiration by 1 hour. The token only expires if the user doesn't make a request for the duration of the expiration time. - -#### Token Reuse - -By default, tokens may be used multiple times. If you want to delete the token after it has been used, you can set the `SingleUseToken` option to `true`. This will delete the token after it has been used, and a new token will be generated on the next request. - -:::info -Using `SingleUseToken` comes with usability trade-offs and is not enabled by default. For example, it can interfere with the user experience if the user has multiple tabs open or uses the back button. -::: - -#### Deleting Tokens - -When the authorization status changes, the CSRF token MUST be deleted, and a new one generated. This can be done by calling `handler.DeleteToken(c)`. - -```go -handler := csrf.HandlerFromContext(ctx) -if handler != nil { - if err := handler.DeleteToken(app.AcquireCtx(ctx)); err != nil { - // handle error - } -} -``` - -:::tip -If you are using this middleware with the fiber session middleware, then you can simply call `session.Destroy()`, `session.Regenerate()`, or `session.Reset()` to delete the session and the token stored therein. -::: - -### BREACH - -It's important to note that the token is sent as a header on every request. If you include the token in a page that is vulnerable to [BREACH](https://en.wikipedia.org/wiki/BREACH), an attacker may be able to extract the token. To mitigate this, ensure your pages are served over HTTPS, disable HTTP compression, and implement rate limiting for requests. diff --git a/versioned_docs/version-v3.x/middleware/earlydata.md b/versioned_docs/version-v3.x/middleware/earlydata.md deleted file mode 100644 index a5ce3219fc4..00000000000 --- a/versioned_docs/version-v3.x/middleware/earlydata.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -id: earlydata ---- - -# EarlyData - -The Early Data middleware for [Fiber](https://github.com/gofiber/fiber) adds support for TLS 1.3's early data ("0-RTT") feature. -Citing [RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446#section-2-3), when a client and server share a PSK, TLS 1.3 allows clients to send data on the first flight ("early data") to speed up the request, effectively reducing the regular 1-RTT request to a 0-RTT request. - -Make sure to enable fiber's `EnableTrustedProxyCheck` config option before using this middleware in order to not trust bogus HTTP request headers of the client. - -Also be aware that enabling support for early data in your reverse proxy (e.g. nginx, as done with a simple `ssl_early_data on;`) makes requests replayable. Refer to the following documents before continuing: - -- https://datatracker.ietf.org/doc/html/rfc8446#section-8 -- https://blog.trailofbits.com/2019/03/25/what-application-developers-need-to-know-about-tls-early-data-0rtt/ - -By default, this middleware allows early data requests on safe HTTP request methods only and rejects the request otherwise, i.e. aborts the request before executing your handler. This behavior can be controlled by the `AllowEarlyData` config option. -Safe HTTP methods β€” `GET`, `HEAD`, `OPTIONS` and `TRACE` β€” should not modify a state on the server. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -func IsEarlyData(c fiber.Ctx) bool -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/earlydata" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use(earlydata.New()) - -// Or extend your config for customization -app.Use(earlydata.New(earlydata.Config{ - Error: fiber.ErrTooEarly, - // ... -})) -``` - -## Config - -| Property | Type | Description | Default | -|:---------------|:------------------------|:-------------------------------------------------------------------------------------|:-------------------------------------------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| IsEarlyData | `func(fiber.Ctx) bool` | IsEarlyData returns whether the request is an early-data request. | Function checking if "Early-Data" header equals "1" | -| AllowEarlyData | `func(fiber.Ctx) bool` | AllowEarlyData returns whether the early-data request should be allowed or rejected. | Function rejecting on unsafe and allowing safe methods | -| Error | `error` | Error is returned in case an early-data request is rejected. | `fiber.ErrTooEarly` | - -## Default Config - -```go -var ConfigDefault = Config{ - IsEarlyData: func(c fiber.Ctx) bool { - return c.Get(DefaultHeaderName) == DefaultHeaderTrueValue - }, - AllowEarlyData: func(c fiber.Ctx) bool { - return fiber.IsMethodSafe(c.Method()) - }, - Error: fiber.ErrTooEarly, -} -``` - -## Constants - -```go -const ( - DefaultHeaderName = "Early-Data" - DefaultHeaderTrueValue = "1" -) -``` diff --git a/versioned_docs/version-v3.x/middleware/encryptcookie.md b/versioned_docs/version-v3.x/middleware/encryptcookie.md deleted file mode 100644 index c153b6412d5..00000000000 --- a/versioned_docs/version-v3.x/middleware/encryptcookie.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -id: encryptcookie ---- - -# Encrypt Cookie - -Encrypt Cookie is a middleware for [Fiber](https://github.com/gofiber/fiber) that secures your cookie values through encryption. - -:::note -This middleware encrypts cookie values and not the cookie names. -::: - -## Signatures - -```go -// Intitializes the middleware -func New(config ...Config) fiber.Handler - -// Returns a random 32 character long string -func GenerateKey() string -``` - -## Examples - -To use the Encrypt Cookie middleware, first, import the middleware package as part of the Fiber web framework: - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/encryptcookie" -) -``` - -Once you've imported the middleware package, you can use it inside your Fiber app: - -```go -// Provide a minimal configuration -app.Use(encryptcookie.New(encryptcookie.Config{ - Key: "secret-thirty-2-character-string", -})) - -// Retrieve the encrypted cookie value -app.Get("/", func(c fiber.Ctx) error { - return c.SendString("value=" + c.Cookies("test")) -}) - -// Create an encrypted cookie -app.Post("/", func(c fiber.Ctx) error { - c.Cookie(&fiber.Cookie{ - Name: "test", - Value: "SomeThing", - }) - return nil -}) -``` - -:::note -`Key` must be a 32 character string. It's used to encrypt the values, so make sure it is random and keep it secret. -You can run `openssl rand -base64 32` or call `encryptcookie.GenerateKey()` to create a random key for you. -Make sure not to set `Key` to `encryptcookie.GenerateKey()` because that will create a new key every run. -::: - -## Config - -| Property | Type | Description | Default | -|:----------|:----------------------------------------------------|:------------------------------------------------------------------------------------------------------|:-----------------------------| -| Next | `func(fiber.Ctx) bool` | A function to skip this middleware when returned true. | `nil` | -| Except | `[]string` | Array of cookie keys that should not be encrypted. | `[]` | -| Key | `string` | A base64-encoded unique key to encode & decode cookies. Required. Key length should be 32 characters. | (No default, required field) | -| Encryptor | `func(decryptedString, key string) (string, error)` | A custom function to encrypt cookies. | `EncryptCookie` | -| Decryptor | `func(encryptedString, key string) (string, error)` | A custom function to decrypt cookies. | `DecryptCookie` | - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, - Except: []string{}, - Key: "", - Encryptor: EncryptCookie, - Decryptor: DecryptCookie, -} -``` - -## Usage With Other Middlewares That Reads Or Modify Cookies -Place the `encryptcookie` middleware before any other middleware that reads or modifies cookies. For example, if you are using the CSRF middleware, ensure that the `encryptcookie` middleware is placed before it. Failure to do so may prevent the CSRF middleware from reading the encrypted cookie. - -You may also choose to exclude certain cookies from encryption. For instance, if you are using the `CSRF` middleware with a frontend framework like Angular, and the framework reads the token from a cookie, you should exclude that cookie from encryption. This can be achieved by adding the cookie name to the Except array in the configuration: - -```go -app.Use(encryptcookie.New(encryptcookie.Config{ - Key: "secret-thirty-2-character-string", - Except: []string{csrf.ConfigDefault.CookieName}, // exclude CSRF cookie -})) -app.Use(csrf.New(csrf.Config{ - KeyLookup: "header:" + csrf.HeaderName, - CookieSameSite: "Lax", - CookieSecure: true, - CookieHTTPOnly: false, -})) -``` diff --git a/versioned_docs/version-v3.x/middleware/envvar.md b/versioned_docs/version-v3.x/middleware/envvar.md deleted file mode 100644 index 3740c38a9f0..00000000000 --- a/versioned_docs/version-v3.x/middleware/envvar.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -id: envvar ---- - -# EnvVar - -EnvVar middleware for [Fiber](https://github.com/gofiber/fiber) that can be used to expose environment variables with various options. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/envvar" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use("/expose/envvars", envvar.New()) - -// Or extend your config for customization -app.Use("/expose/envvars", envvar.New( - envvar.Config{ - ExportVars: map[string]string{"testKey": "", "testDefaultKey": "testDefaultVal"}, - ExcludeVars: map[string]string{"excludeKey": ""}, - }), -) -``` - -:::note -You will need to provide a path to use the envvar middleware. -::: - -## Response - -Http response contract: -``` -{ - "vars": { - "someEnvVariable": "someValue", - "anotherEnvVariable": "anotherValue", - } -} - -``` - -## Config - -| Property | Type | Description | Default | -|:------------|:--------------------|:-----------------------------------------------------------------------------|:--------| -| ExportVars | `map[string]string` | ExportVars specifies the environment variables that should be exported. | `nil` | -| ExcludeVars | `map[string]string` | ExcludeVars specifies the environment variables that should not be exported. | `nil` | - -## Default Config - -```go -Config{} -``` diff --git a/versioned_docs/version-v3.x/middleware/etag.md b/versioned_docs/version-v3.x/middleware/etag.md deleted file mode 100644 index 28cf69195e8..00000000000 --- a/versioned_docs/version-v3.x/middleware/etag.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -id: etag ---- - -# ETag - -ETag middleware for [Fiber](https://github.com/gofiber/fiber) that lets caches be more efficient and save bandwidth, as a web server does not need to resend a full response if the content has not changed. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/etag" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use(etag.New()) - -// Get / receives Etag: "13-1831710635" in response header -app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") -}) - -// Or extend your config for customization -app.Use(etag.New(etag.Config{ - Weak: true, -})) - -// Get / receives Etag: "W/"13-1831710635" in response header -app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") -}) -``` - -## Config - -| Property | Type | Description | Default | -|:---------|:------------------------|:-------------------------------------------------------------------------------------------------------------------|:--------| -| Weak | `bool` | Weak indicates that a weak validator is used. Weak etags are easy to generate but are less useful for comparisons. | `false` | -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, - Weak: false, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/expvar.md b/versioned_docs/version-v3.x/middleware/expvar.md deleted file mode 100644 index 8299b8fd443..00000000000 --- a/versioned_docs/version-v3.x/middleware/expvar.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -id: expvar ---- - -# ExpVar - -Expvar middleware for [Fiber](https://github.com/gofiber/fiber) that serves via its HTTP server runtime exposed variants in the JSON format. The package is typically only imported for the side effect of registering its HTTP handlers. The handled path is `/debug/vars`. - -## Signatures - -```go -func New() fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - expvarmw "github.com/gofiber/fiber/v3/middleware/expvar" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: -```go -var count = expvar.NewInt("count") - -app.Use(expvarmw.New()) -app.Get("/", func(c fiber.Ctx) error { - count.Add(1) - - return c.SendString(fmt.Sprintf("hello expvar count %d", count.Value())) -}) -``` - -Visit path `/debug/vars` to see all vars and use query `r=key` to filter exposed variables. - -```bash -curl 127.0.0.1:3000 -hello expvar count 1 - -curl 127.0.0.1:3000/debug/vars -{ - "cmdline": ["xxx"], - "count": 1, - "expvarHandlerCalls": 33, - "expvarRegexpErrors": 0, - "memstats": {...} -} - -curl 127.0.0.1:3000/debug/vars?r=c -{ - "cmdline": ["xxx"], - "count": 1 -} -``` - -## Config - -| Property | Type | Description | Default | -|:---------|:------------------------|:--------------------------------------------------------------------|:--------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/favicon.md b/versioned_docs/version-v3.x/middleware/favicon.md deleted file mode 100644 index ddb0a7a7dd5..00000000000 --- a/versioned_docs/version-v3.x/middleware/favicon.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -id: favicon ---- - -# Favicon - -Favicon middleware for [Fiber](https://github.com/gofiber/fiber) that ignores favicon requests or caches a provided icon in memory to improve performance by skipping disk access. User agents request favicon.ico frequently and indiscriminately, so you may wish to exclude these requests from your logs by using this middleware before your logger middleware. - -:::note -This middleware is exclusively for serving the default, implicit favicon, which is GET /favicon.ico or [custom favicon URL](#config). -::: - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/favicon" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use(favicon.New()) - -// Or extend your config for customization -app.Use(favicon.New(favicon.Config{ - File: "./favicon.ico", - URL: "/favicon.ico", -})) -``` - -## Config - -| Property | Type | Description | Default | -|:-------------|:------------------------|:---------------------------------------------------------------------------------|:---------------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Data | `[]byte` | Raw data of the favicon file. This can be used instead of `File`. | `nil` | -| File | `string` | File holds the path to an actual favicon that will be cached. | "" | -| URL | `string` | URL for favicon handler. | "/favicon.ico" | -| FileSystem | `http.FileSystem` | FileSystem is an optional alternate filesystem to search for the favicon in. | `nil` | -| CacheControl | `string` | CacheControl defines how the Cache-Control header in the response should be set. | "public, max-age=31536000" | - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, - File: "", - URL: fPath, - CacheControl: "public, max-age=31536000", -} -``` diff --git a/versioned_docs/version-v3.x/middleware/healthcheck.md b/versioned_docs/version-v3.x/middleware/healthcheck.md deleted file mode 100644 index d99e08517fe..00000000000 --- a/versioned_docs/version-v3.x/middleware/healthcheck.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: healthcheck ---- - -# Health Check - -Liveness and readiness probes middleware for [Fiber](https://github.com/gofiber/fiber) that provides two endpoints for checking the liveness and readiness state of HTTP applications. - -## Overview - -- **Liveness Probe**: Checks if the server is up and running. - - **Default Endpoint**: `/livez` - - **Behavior**: By default returns `true` immediately when the server is operational. - -- **Readiness Probe**: Assesses if the application is ready to handle requests. - - **Default Endpoint**: `/readyz` - - **Behavior**: By default returns `true` immediately when the server is operational. - -- **HTTP Status Codes**: - - `200 OK`: Returned when the checker function evaluates to `true`. - - `503 Service Unavailable`: Returned when the checker function evaluates to `false`. - -## Signatures - -```go -func NewHealthChecker(config Config) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the [Fiber](https://github.com/gofiber/fiber) web framework -```go -import( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/healthcheck" -) -``` - -After you initiate your [Fiber](https://github.com/gofiber/fiber) app, you can use the following possibilities: - -```go -// Provide a minimal config for liveness check -app.Get(healthcheck.DefaultLivenessEndpoint, healthcheck.NewHealthChecker()) -// Provide a minimal config for readiness check -app.Get(healthcheck.DefaultReadinessEndpoint, healthcheck.NewHealthChecker()) -// Provide a minimal config for check with custom endpoint -app.Get("/live", healthcheck.NewHealthChecker()) - -// Or extend your config for customization -app.Get(healthcheck.DefaultLivenessEndpoint, healthcheck.NewHealthChecker(healthcheck.Config{ - Probe: func(c fiber.Ctx) bool { - return true - }, -})) -// And it works the same for readiness, just change the route -app.Get(healthcheck.DefaultReadinessEndpoint, healthcheck.NewHealthChecker(healthcheck.Config{ - Probe: func(c fiber.Ctx) bool { - return true - }, -})) -// With a custom route and custom probe -app.Get("/live", healthcheck.NewHealthChecker(healthcheck.Config{ - Probe: func(c fiber.Ctx) bool { - return true - }, -})) - -// It can also be used with app.All, although it will only respond to requests with the GET method -// in case of calling the route with any method which isn't GET, the return will be 404 Not Found when app.All is used -// and 405 Method Not Allowed when app.Get is used -app.All(healthcheck.DefaultReadinessEndpoint, healthcheck.NewHealthChecker(healthcheck.Config{ - Probe: func(c fiber.Ctx) bool { - return true - }, -})) -``` - -## Config - -```go -type Config struct { - // Next defines a function to skip this middleware when returned true. If this function returns true - // and no other handlers are defined for the route, Fiber will return a status 404 Not Found, since - // no other handlers were defined to return a different status. - // - // Optional. Default: nil - Next func(fiber.Ctx) bool - - // Function used for checking the liveness of the application. Returns true if the application - // is running and false if it is not. The liveness probe is typically used to indicate if - // the application is in a state where it can handle requests (e.g., the server is up and running). - // - // Optional. Default: func(c fiber.Ctx) bool { return true } - Probe HealthChecker -} -``` - -## Default Config - -The default configuration used by this middleware is defined as follows: -```go -func defaultProbe(fiber.Ctx) bool { return true } - -var ConfigDefault = Config{ - Probe: defaultProbe, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/helmet.md b/versioned_docs/version-v3.x/middleware/helmet.md deleted file mode 100644 index b0dca52d544..00000000000 --- a/versioned_docs/version-v3.x/middleware/helmet.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: helmet ---- - -# Helmet - -Helmet middleware helps secure your apps by setting various HTTP headers. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Examples -```go -package main - -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/helmet" -) - -func main() { - app := fiber.New() - - app.Use(helmet.New()) - - app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Welcome!") - }) - - app.Listen(":3000") -} -``` - -**Test:** - -```curl -curl -I http://localhost:3000 -``` - -## Config - -| Property | Type | Description | Default | -|:--------------------------|:------------------------|:--------------------------------------------|:-----------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip middleware. | `nil` | -| XSSProtection | `string` | XSSProtection | "0" | -| ContentTypeNosniff | `string` | ContentTypeNosniff | "nosniff" | -| XFrameOptions | `string` | XFrameOptions | "SAMEORIGIN" | -| HSTSMaxAge | `int` | HSTSMaxAge | 0 | -| HSTSExcludeSubdomains | `bool` | HSTSExcludeSubdomains | false | -| ContentSecurityPolicy | `string` | ContentSecurityPolicy | "" | -| CSPReportOnly | `bool` | CSPReportOnly | false | -| HSTSPreloadEnabled | `bool` | HSTSPreloadEnabled | false | -| ReferrerPolicy | `string` | ReferrerPolicy | "ReferrerPolicy" | -| PermissionPolicy | `string` | Permissions-Policy | "" | -| CrossOriginEmbedderPolicy | `string` | Cross-Origin-Embedder-Policy | "require-corp" | -| CrossOriginOpenerPolicy | `string` | Cross-Origin-Opener-Policy | "same-origin" | -| CrossOriginResourcePolicy | `string` | Cross-Origin-Resource-Policy | "same-origin" | -| OriginAgentCluster | `string` | Origin-Agent-Cluster | "?1" | -| XDNSPrefetchControl | `string` | X-DNS-Prefetch-Control | "off" | -| XDownloadOptions | `string` | X-Download-Options | "noopen" | -| XPermittedCrossDomain | `string` | X-Permitted-Cross-Domain-Policies | "none" | - -## Default Config - -```go -var ConfigDefault = Config{ - XSSProtection: "0", - ContentTypeNosniff: "nosniff", - XFrameOptions: "SAMEORIGIN", - ReferrerPolicy: "no-referrer", - CrossOriginEmbedderPolicy: "require-corp", - CrossOriginOpenerPolicy: "same-origin", - CrossOriginResourcePolicy: "same-origin", - OriginAgentCluster: "?1", - XDNSPrefetchControl: "off", - XDownloadOptions: "noopen", - XPermittedCrossDomain: "none", -} -``` diff --git a/versioned_docs/version-v3.x/middleware/idempotency.md b/versioned_docs/version-v3.x/middleware/idempotency.md deleted file mode 100644 index 475ec9dfc38..00000000000 --- a/versioned_docs/version-v3.x/middleware/idempotency.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -id: idempotency ---- - -# Idempotency - -Idempotency middleware for [Fiber](https://github.com/gofiber/fiber) allows for fault-tolerant APIs where duplicate requests β€” for example due to networking issues on the client-side β€” do not erroneously cause the same action performed multiple times on the server-side. - -Refer to https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-idempotency-key-header-02 for a better understanding. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -func IsFromCache(c fiber.Ctx) bool -func WasPutToCache(c fiber.Ctx) bool -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/idempotency" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -### Default Config - -```go -app.Use(idempotency.New()) -``` - -### Custom Config - -```go -app.Use(idempotency.New(idempotency.Config{ - Lifetime: 42 * time.Minute, - // ... -})) -``` - -### Config - -| Property | Type | Description | Default | -|:--------------------|:------------------------|:-----------------------------------------------------------------------------------------|:-------------------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | A function for safe methods | -| Lifetime | `time.Duration` | Lifetime is the maximum lifetime of an idempotency key. | 30 * time.Minute | -| KeyHeader | `string` | KeyHeader is the name of the header that contains the idempotency key. | "X-Idempotency-Key" | -| KeyHeaderValidate | `func(string) error` | KeyHeaderValidate defines a function to validate the syntax of the idempotency header. | A function for UUID validation | -| KeepResponseHeaders | `[]string` | KeepResponseHeaders is a list of headers that should be kept from the original response. | nil (keep all headers) | -| Lock | `Locker` | Lock locks an idempotency key. | An in-memory locker | -| Storage | `fiber.Storage` | Storage stores response data by idempotency key. | An in-memory storage | - -## Default Config - -```go -var ConfigDefault = Config{ - Next: func(c fiber.Ctx) bool { - // Skip middleware if the request was done using a safe HTTP method - return fiber.IsMethodSafe(c.Method()) - }, - - Lifetime: 30 * time.Minute, - - KeyHeader: "X-Idempotency-Key", - KeyHeaderValidate: func(k string) error { - if l, wl := len(k), 36; l != wl { // UUID length is 36 chars - return fmt.Errorf("%w: invalid length: %d != %d", ErrInvalidIdempotencyKey, l, wl) - } - - return nil - }, - - KeepResponseHeaders: nil, - - Lock: nil, // Set in configDefault so we don't allocate data here. - - Storage: nil, // Set in configDefault so we don't allocate data here. -} -``` diff --git a/versioned_docs/version-v3.x/middleware/keyauth.md b/versioned_docs/version-v3.x/middleware/keyauth.md deleted file mode 100644 index 9907a5dabf3..00000000000 --- a/versioned_docs/version-v3.x/middleware/keyauth.md +++ /dev/null @@ -1,250 +0,0 @@ ---- -id: keyauth ---- - -# Keyauth - -Key auth middleware provides a key based authentication. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -func TokenFromContext(c fiber.Ctx) string -``` - -## Examples - -```go -package main - -import ( - "crypto/sha256" - "crypto/subtle" - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/keyauth" -) - -var ( - apiKey = "correct horse battery staple" -) - -func validateAPIKey(c fiber.Ctx, key string) (bool, error) { - hashedAPIKey := sha256.Sum256([]byte(apiKey)) - hashedKey := sha256.Sum256([]byte(key)) - - if subtle.ConstantTimeCompare(hashedAPIKey[:], hashedKey[:]) == 1 { - return true, nil - } - return false, keyauth.ErrMissingOrMalformedAPIKey -} - -func main() { - app := fiber.New() - - // note that the keyauth middleware needs to be defined before the routes are defined! - app.Use(keyauth.New(keyauth.Config{ - KeyLookup: "cookie:access_token", - Validator: validateAPIKey, - })) - - app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Successfully authenticated!") - }) - - app.Listen(":3000") -} -``` - -**Test:** - -```bash -# No api-key specified -> 400 missing -curl http://localhost:3000 -#> missing or malformed API Key - -curl --cookie "access_token=correct horse battery staple" http://localhost:3000 -#> Successfully authenticated! - -curl --cookie "access_token=Clearly A Wrong Key" http://localhost:3000 -#> missing or malformed API Key -``` - -For a more detailed example, see also the [`github.com/gofiber/recipes`](https://github.com/gofiber/recipes) repository and specifically the `fiber-envoy-extauthz` repository and the [`keyauth example`](https://github.com/gofiber/recipes/blob/master/fiber-envoy-extauthz/authz/main.go) code. - - -### Authenticate only certain endpoints - -If you want to authenticate only certain endpoints, you can use the `Config` of keyauth and apply a filter function (eg. `authFilter`) like so - -```go -package main - -import ( - "crypto/sha256" - "crypto/subtle" - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/keyauth" - "regexp" - "strings" -) - -var ( - apiKey = "correct horse battery staple" - protectedURLs = []*regexp.Regexp{ - regexp.MustCompile("^/authenticated$"), - regexp.MustCompile("^/auth2$"), - } -) - -func validateAPIKey(c fiber.Ctx, key string) (bool, error) { - hashedAPIKey := sha256.Sum256([]byte(apiKey)) - hashedKey := sha256.Sum256([]byte(key)) - - if subtle.ConstantTimeCompare(hashedAPIKey[:], hashedKey[:]) == 1 { - return true, nil - } - return false, keyauth.ErrMissingOrMalformedAPIKey -} - -func authFilter(c fiber.Ctx) bool { - originalURL := strings.ToLower(c.OriginalURL()) - - for _, pattern := range protectedURLs { - if pattern.MatchString(originalURL) { - return false - } - } - return true -} - -func main() { - app := fiber.New() - - app.Use(keyauth.New(keyauth.Config{ - Next: authFilter, - KeyLookup: "cookie:access_token", - Validator: validateAPIKey, - })) - - app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Welcome") - }) - app.Get("/authenticated", func(c fiber.Ctx) error { - return c.SendString("Successfully authenticated!") - }) - app.Get("/auth2", func(c fiber.Ctx) error { - return c.SendString("Successfully authenticated 2!") - }) - - app.Listen(":3000") -} -``` - -Which results in this - -```bash -# / does not need to be authenticated -curl http://localhost:3000 -#> Welcome - -# /authenticated needs to be authenticated -curl --cookie "access_token=correct horse battery staple" http://localhost:3000/authenticated -#> Successfully authenticated! - -# /auth2 needs to be authenticated too -curl --cookie "access_token=correct horse battery staple" http://localhost:3000/auth2 -#> Successfully authenticated 2! -``` - -### Specifying middleware in the handler - -```go -package main - -import ( - "crypto/sha256" - "crypto/subtle" - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/keyauth" -) - -const ( - apiKey = "my-super-secret-key" -) - -func main() { - app := fiber.New() - - authMiddleware := keyauth.New(keyauth.Config{ - Validator: func(c fiber.Ctx, key string) (bool, error) { - hashedAPIKey := sha256.Sum256([]byte(apiKey)) - hashedKey := sha256.Sum256([]byte(key)) - - if subtle.ConstantTimeCompare(hashedAPIKey[:], hashedKey[:]) == 1 { - return true, nil - } - return false, keyauth.ErrMissingOrMalformedAPIKey - }, - }) - - app.Get("/", func(c fiber.Ctx) error { - return c.SendString("Welcome") - }) - - app.Get("/allowed", authMiddleware, func(c fiber.Ctx) error { - return c.SendString("Successfully authenticated!") - }) - - app.Listen(":3000") -} -``` - -Which results in this - -```bash -# / does not need to be authenticated -curl http://localhost:3000 -#> Welcome - -# /allowed needs to be authenticated too -curl --header "Authorization: Bearer my-super-secret-key" http://localhost:3000/allowed -#> Successfully authenticated! -``` - -## Config - -| Property | Type | Description | Default | -|:----------------|:-----------------------------------------|:-------------------------------------------------------------------------------------------------------|:------------------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| SuccessHandler | `fiber.Handler` | SuccessHandler defines a function which is executed for a valid key. | `nil` | -| ErrorHandler | `fiber.ErrorHandler` | ErrorHandler defines a function which is executed for an invalid key. | `401 Invalid or expired key` | -| KeyLookup | `string` | KeyLookup is a string in the form of "`:`" that is used to extract the key from the request. | "header:Authorization" | -| CustomKeyLookup | `KeyLookupFunc` aka `func(c fiber.Ctx) (string, error)` | If more complex logic is required to extract the key from the request, an arbitrary function to extract it can be specified here. Utility helper functions are described below. | `nil` | -| AuthScheme | `string` | AuthScheme to be used in the Authorization header. | "Bearer" | -| Validator | `func(fiber.Ctx, string) (bool, error)` | Validator is a function to validate the key. | A function for key validation | - -## Default Config - -```go -var ConfigDefault = Config{ - SuccessHandler: func(c fiber.Ctx) error { - return c.Next() - }, - ErrorHandler: func(c fiber.Ctx, err error) error { - if err == ErrMissingOrMalformedAPIKey { - return c.Status(fiber.StatusUnauthorized).SendString(err.Error()) - } - return c.Status(fiber.StatusUnauthorized).SendString("Invalid or expired API Key") - }, - KeyLookup: "header:" + fiber.HeaderAuthorization, - CustomKeyLookup: nil, - AuthScheme: "Bearer", -} -``` - -## CustomKeyLookup - -Two public utility functions are provided that may be useful when creating custom extraction: -* `DefaultKeyLookup(keyLookup string, authScheme string)`: This is the function that implements the default `KeyLookup` behavior, exposed to be used as a component of custom parsing logic -* `MultipleKeySourceLookup(keyLookups []string, authScheme string)`: Creates a CustomKeyLookup function that checks each listed source using the above function until a key is found or the options are all exhausted. For example, `MultipleKeySourceLookup([]string{"header:Authorization", "header:x-api-key", "cookie:apikey"}, "Bearer")` would first check the standard Authorization header, checks the `x-api-key` header next, and finally checks for a cookie named `apikey`. If any of these contain a valid API key, the request continues. Otherwise, an error is returned. diff --git a/versioned_docs/version-v3.x/middleware/limiter.md b/versioned_docs/version-v3.x/middleware/limiter.md deleted file mode 100644 index 30986251c44..00000000000 --- a/versioned_docs/version-v3.x/middleware/limiter.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -id: limiter ---- - -# Limiter - -Limiter middleware for [Fiber](https://github.com/gofiber/fiber) that is used to limit repeat requests to public APIs and/or endpoints such as password reset. It is also useful for API clients, web crawling, or other tasks that need to be throttled. - -:::note -This middleware uses our [Storage](https://github.com/gofiber/storage) package to support various databases through a single interface. The default configuration for this middleware saves data to memory, see the examples below for other databases. -::: - -:::note -This module does not share state with other processes/servers by default. -::: - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/limiter" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use(limiter.New()) - -// Or extend your config for customization -app.Use(limiter.New(limiter.Config{ - Next: func(c fiber.Ctx) bool { - return c.IP() == "127.0.0.1" - }, - Max: 20, - Expiration: 30 * time.Second, - KeyGenerator: func(c fiber.Ctx) string { - return c.Get("x-forwarded-for") - }, - LimitReached: func(c fiber.Ctx) error { - return c.SendFile("./toofast.html") - }, - Storage: myCustomStorage{}, -})) -``` - -## Sliding window - -Instead of using the standard fixed window algorithm, you can enable the [sliding window](https://en.wikipedia.org/wiki/Sliding_window_protocol) algorithm. - -A example of such configuration is: - -```go -app.Use(limiter.New(limiter.Config{ - Max: 20, - Expiration: 30 * time.Second, - LimiterMiddleware: limiter.SlidingWindow{}, -})) -``` - -This means that every window will take into account the previous window(if there was any). The given formula for the rate is: -``` -weightOfPreviousWindpw = previous window's amount request * (whenNewWindow / Expiration) -rate = weightOfPreviousWindpw + current window's amount request. -``` - -## Config - -| Property | Type | Description | Default | -|:-----------------------|:--------------------------|:--------------------------------------------------------------------------------------------|:-----------------------------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Max | `int` | Max number of recent connections during `Expiration` seconds before sending a 429 response. | 5 | -| KeyGenerator | `func(fiber.Ctx) string` | KeyGenerator allows you to generate custom keys, by default c.IP() is used. | A function using c.IP() as the default | -| Expiration | `time.Duration` | Expiration is the time on how long to keep records of requests in memory. | 1 * time.Minute | -| LimitReached | `fiber.Handler` | LimitReached is called when a request hits the limit. | A function sending 429 response | -| SkipFailedRequests | `bool` | When set to true, requests with StatusCode >= 400 won't be counted. | false | -| SkipSuccessfulRequests | `bool` | When set to true, requests with StatusCode < 400 won't be counted. | false | -| Storage | `fiber.Storage` | Store is used to store the state of the middleware. | An in-memory store for this process only | -| LimiterMiddleware | `LimiterHandler` | LimiterMiddleware is the struct that implements a limiter middleware. | A new Fixed Window Rate Limiter | -| Duration (Deprecated) | `time.Duration` | Deprecated: Use Expiration instead | - | -| Store (Deprecated) | `fiber.Storage` | Deprecated: Use Storage instead | - | -| Key (Deprecated) | `func(fiber.Ctx) string` | Deprecated: Use KeyGenerator instead | - | - -:::note -A custom store can be used if it implements the `Storage` interface - more details and an example can be found in `store.go`. -::: - -## Default Config - -```go -var ConfigDefault = Config{ - Max: 5, - Expiration: 1 * time.Minute, - KeyGenerator: func(c fiber.Ctx) string { - return c.IP() - }, - LimitReached: func(c fiber.Ctx) error { - return c.SendStatus(fiber.StatusTooManyRequests) - }, - SkipFailedRequests: false, - SkipSuccessfulRequests: false, - LimiterMiddleware: FixedWindow{}, -} -``` - -### Custom Storage/Database - -You can use any storage from our [storage](https://github.com/gofiber/storage/) package. - -```go -storage := sqlite3.New() // From github.com/gofiber/storage/sqlite3 -app.Use(limiter.New(limiter.Config{ - Storage: storage, -})) -``` diff --git a/versioned_docs/version-v3.x/middleware/logger.md b/versioned_docs/version-v3.x/middleware/logger.md deleted file mode 100644 index 7c147ba0dd4..00000000000 --- a/versioned_docs/version-v3.x/middleware/logger.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -id: logger ---- - -# Logger - -Logger middleware for [Fiber](https://github.com/gofiber/fiber) that logs HTTP request/response details. - -## Signatures -```go -func New(config ...Config) fiber.Handler -``` -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/logger" -) -``` - -:::tip -The order of registration plays a role. Only all routes that are registered after this one will be logged. -The middleware should therefore be one of the first to be registered. -::: - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use(logger.New()) - -// Or extend your config for customization -// Logging remote IP and Port -app.Use(logger.New(logger.Config{ - Format: "[${ip}]:${port} ${status} - ${method} ${path}\n", -})) - -// Logging Request ID -app.Use(requestid.New()) -app.Use(logger.New(logger.Config{ - // For more options, see the Config section - Format: "${pid} ${locals:requestid} ${status} - ${method} ${path}​\n", -})) - -// Changing TimeZone & TimeFormat -app.Use(logger.New(logger.Config{ - Format: "${pid} ${status} - ${method} ${path}\n", - TimeFormat: "02-Jan-2006", - TimeZone: "America/New_York", -})) - -// Custom File Writer -file, err := os.OpenFile("./123.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) -if err != nil { - log.Fatalf("error opening file: %v", err) -} -defer file.Close() -app.Use(logger.New(logger.Config{ - Output: file, -})) - -// Add Custom Tags -app.Use(logger.New(logger.Config{ - CustomTags: map[string]logger.LogFunc{ - "custom_tag": func(output logger.Buffer, c fiber.Ctx, data *logger.Data, extraParam string) (int, error) { - return output.WriteString("it is a custom tag") - }, - }, -})) - -// Callback after log is written -app.Use(logger.New(logger.Config{ - TimeFormat: time.RFC3339Nano, - TimeZone: "Asia/Shanghai", - Done: func(c fiber.Ctx, logString []byte) { - if c.Response().StatusCode() != fiber.StatusOK { - reporter.SendToSlack(logString) - } - }, -})) - -// Disable colors when outputting to default format -app.Use(logger.New(logger.Config{ - DisableColors: true, -})) -``` - -:::tip -Writing to os.File is goroutine-safe, but if you are using a custom Output that is not goroutine-safe, make sure to implement locking to properly serialize writes. -::: - -## Config - -### Config - -| Property | Type | Description | Default | -|:-----------------|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Done | `func(fiber.Ctx, []byte)` | Done is a function that is called after the log string for a request is written to Output, and pass the log string as parameter. | `nil` | -| CustomTags | `map[string]LogFunc` | tagFunctions defines the custom tag action. | `map[string]LogFunc` | -| Format | `string` | Format defines the logging tags. | `[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n` | -| TimeFormat | `string` | TimeFormat defines the time format for log timestamps. | `15:04:05` | -| TimeZone | `string` | TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc | `"Local"` | -| TimeInterval | `time.Duration` | TimeInterval is the delay before the timestamp is updated. | `500 * time.Millisecond` | -| Output | `io.Writer` | Output is a writer where logs are written. | `os.Stdout` | -| DisableColors | `bool` | DisableColors defines if the logs output should be colorized. | `false` | -| enableColors | `bool` | Internal field for enabling colors in the log output. (This is not a user-configurable field) | - | -| enableLatency | `bool` | Internal field for enabling latency measurement in logs. (This is not a user-configurable field) | - | -| timeZoneLocation | `*time.Location` | Internal field for the time zone location. (This is not a user-configurable field) | - | - -## Default Config -```go -var ConfigDefault = Config{ - Next: nil, - Done: nil, - Format: "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n", - TimeFormat: "15:04:05", - TimeZone: "Local", - TimeInterval: 500 * time.Millisecond, - Output: os.Stdout, - DisableColors: false, -} -``` - -## Constants -```go -// Logger variables -const ( - TagPid = "pid" - TagTime = "time" - TagReferer = "referer" - TagProtocol = "protocol" - TagPort = "port" - TagIP = "ip" - TagIPs = "ips" - TagHost = "host" - TagMethod = "method" - TagPath = "path" - TagURL = "url" - TagUA = "ua" - TagLatency = "latency" - TagStatus = "status" // response status - TagResBody = "resBody" // response body - TagReqHeaders = "reqHeaders" - TagQueryStringParams = "queryParams" // request query parameters - TagBody = "body" // request body - TagBytesSent = "bytesSent" - TagBytesReceived = "bytesReceived" - TagRoute = "route" - TagError = "error" - // DEPRECATED: Use TagReqHeader instead - TagHeader = "header:" // request header - TagReqHeader = "reqHeader:" // request header - TagRespHeader = "respHeader:" // response header - TagQuery = "query:" // request query - TagForm = "form:" // request form - TagCookie = "cookie:" // request cookie - TagLocals = "locals:" - // colors - TagBlack = "black" - TagRed = "red" - TagGreen = "green" - TagYellow = "yellow" - TagBlue = "blue" - TagMagenta = "magenta" - TagCyan = "cyan" - TagWhite = "white" - TagReset = "reset" -) -``` diff --git a/versioned_docs/version-v3.x/middleware/monitor.md b/versioned_docs/version-v3.x/middleware/monitor.md deleted file mode 100644 index b314c66bce7..00000000000 --- a/versioned_docs/version-v3.x/middleware/monitor.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -id: monitor ---- - -# Monitor - -Monitor middleware for [Fiber](https://github.com/gofiber/fiber) that reports server metrics, inspired by [express-status-monitor](https://github.com/RafalWilinski/express-status-monitor) - -:::caution - -Monitor is still in beta, API might change in the future! - -::: - -![](https://i.imgur.com/nHAtBpJ.gif) - -### Signatures -```go -func New() fiber.Handler -``` - -### Examples -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/monitor" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: -```go -// Initialize default config (Assign the middleware to /metrics) -app.Get("/metrics", monitor.New()) - -// Or extend your config for customization -// Assign the middleware to /metrics -// and change the Title to `MyService Metrics Page` -app.Get("/metrics", monitor.New(monitor.Config{Title: "MyService Metrics Page"})) -``` -You can also access the API endpoint with -`curl -X GET -H "Accept: application/json" http://localhost:3000/metrics` which returns: -```json -{"pid":{ "cpu":0.4568381746582226, "ram":20516864, "conns":3 }, - "os": { "cpu":8.759124087593099, "ram":3997155328, "conns":44, - "total_ram":8245489664, "load_avg":0.51 }} -``` - -## Config - -| Property | Type | Description | Default | -|:-----------|:------------------------|:--------------------------------------------------------------------|:----------------------------------------------------------------------------| -| Title | `string` | Metrics page title | "Fiber Monitor" | -| Refresh | `time.Duration` | Refresh period | 3 seconds | -| APIOnly | `bool` | Whether the service should expose only the monitoring API | false | -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| CustomHead | `string` | Custom HTML Code to Head Section(Before End) | empty | -| FontURL | `string` | FontURL for specify font resource path or URL | "https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap" | -| ChartJsURL | `string` | ChartJsURL for specify ChartJS library path or URL | "https://cdn.jsdelivr.net/npm/chart.js@2.9/dist/Chart.bundle.min.js" | - -## Default Config - -```go -var ConfigDefault = Config{ - Title: defaultTitle, - Refresh: defaultRefresh, - FontURL: defaultFontURL, - ChartJsURL: defaultChartJSURL, - CustomHead: defaultCustomHead, - APIOnly: false, - Next: nil, - index: newIndex(viewBag{ - defaultTitle, - defaultRefresh, - defaultFontURL, - defaultChartJSURL, - defaultCustomHead, - }), -} -``` diff --git a/versioned_docs/version-v3.x/middleware/pprof.md b/versioned_docs/version-v3.x/middleware/pprof.md deleted file mode 100644 index bbac32fd1f2..00000000000 --- a/versioned_docs/version-v3.x/middleware/pprof.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -id: pprof ---- - -# Pprof - -Pprof middleware for [Fiber](https://github.com/gofiber/fiber) that serves via its HTTP server runtime profiling data in the format expected by the pprof visualization tool. The package is typically only imported for the side effect of registering its HTTP handlers. The handled paths all begin with /debug/pprof/. - -## Signatures - -```go -func New() fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/pprof" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use(pprof.New()) - -// Or extend your config for customization - -// For example, in systems where you have multiple ingress endpoints, it is common to add a URL prefix, like so: -app.Use(pprof.New(pprof.Config{Prefix: "/endpoint-prefix"})) - -// This prefix will be added to the default path of "/debug/pprof/", for a resulting URL of: "/endpoint-prefix/debug/pprof/". -``` - -## Config - -| Property | Type | Description | Default | -|:---------|:------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------|:--------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Prefix | `string` | Prefix defines a URL prefix added before "/debug/pprof". Note that it should start with (but not end with) a slash. Example: "/federated-fiber" | "" | - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/proxy.md b/versioned_docs/version-v3.x/middleware/proxy.md deleted file mode 100644 index 08d00b35c55..00000000000 --- a/versioned_docs/version-v3.x/middleware/proxy.md +++ /dev/null @@ -1,179 +0,0 @@ ---- -id: proxy ---- - -# Proxy - -Proxy middleware for [Fiber](https://github.com/gofiber/fiber) that allows you to proxy requests to multiple servers. - -## Signatures -// BalancerForward performs the given http request based on a round-robin balancer and fills the given http response. - -```go -// Balancer create a load balancer among multiple upstream servers. -func Balancer(config Config) fiber.Handler -// Forward performs the given http request and fills the given http response. -func Forward(addr string, clients ...*fasthttp.Client) fiber.Handler -// Do performs the given http request and fills the given http response. -func Do(c fiber.Ctx, addr string, clients ...*fasthttp.Client) error -// DoRedirects performs the given http request and fills the given http response while following up to maxRedirectsCount redirects. -func DoRedirects(c fiber.Ctx, addr string, maxRedirectsCount int, clients ...*fasthttp.Client) error -// DoDeadline performs the given request and waits for response until the given deadline. -func DoDeadline(c fiber.Ctx, addr string, deadline time.Time, clients ...*fasthttp.Client) error -// DoTimeout performs the given request and waits for response during the given timeout duration. -func DoTimeout(c fiber.Ctx, addr string, timeout time.Duration, clients ...*fasthttp.Client) error -// DomainForward the given http request based on the given domain and fills the given http response. -func DomainForward(hostname string, addr string, clients ...*fasthttp.Client) fiber.Handler -// BalancerForward performs the given http request based round robin balancer and fills the given http response. -func BalancerForward(servers []string, clients ...*fasthttp.Client) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/proxy" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// if target https site uses a self-signed certificate, you should -// call WithTLSConfig before Do and Forward -proxy.WithTLSConfig(&tls.Config{ - InsecureSkipVerify: true, -}) -// if you need to use global self-custom client, you should use proxy.WithClient. -proxy.WithClient(&fasthttp.Client{ - NoDefaultUserAgentHeader: true, - DisablePathNormalizing: true, -}) - -// Forward to url -app.Get("/gif", proxy.Forward("https://i.imgur.com/IWaBepg.gif")) - -// If you want to forward with a specific domain. You have to use proxy.DomainForward. -app.Get("/payments", proxy.DomainForward("docs.gofiber.io", "http://localhost:8000")) - -// Forward to url with local custom client -app.Get("/gif", proxy.Forward("https://i.imgur.com/IWaBepg.gif", &fasthttp.Client{ - NoDefaultUserAgentHeader: true, - DisablePathNormalizing: true, -})) - -// Make request within handler -app.Get("/:id", func(c fiber.Ctx) error { - url := "https://i.imgur.com/"+c.Params("id")+".gif" - if err := proxy.Do(c, url); err != nil { - return err - } - // Remove Server header from response - c.Response().Header.Del(fiber.HeaderServer) - return nil -}) - -// Make proxy requests while following redirects -app.Get("/proxy", func(c fiber.Ctx) error { - if err := proxy.DoRedirects(c, "http://google.com", 3); err != nil { - return err - } - // Remove Server header from response - c.Response().Header.Del(fiber.HeaderServer) - return nil -}) - -// Make proxy requests and wait up to 5 seconds before timing out -app.Get("/proxy", func(c fiber.Ctx) error { - if err := proxy.DoTimeout(c, "http://localhost:3000", time.Second * 5); err != nil { - return err - } - // Remove Server header from response - c.Response().Header.Del(fiber.HeaderServer) - return nil -}) - -// Make proxy requests, timeout a minute from now -app.Get("/proxy", func(c fiber.Ctx) error { - if err := proxy.DoDeadline(c, "http://localhost", time.Now().Add(time.Minute)); err != nil { - return err - } - // Remove Server header from response - c.Response().Header.Del(fiber.HeaderServer) - return nil -}) - -// Minimal round robin balancer -app.Use(proxy.Balancer(proxy.Config{ - Servers: []string{ - "http://localhost:3001", - "http://localhost:3002", - "http://localhost:3003", - }, -})) - -// Or extend your balancer for customization -app.Use(proxy.Balancer(proxy.Config{ - Servers: []string{ - "http://localhost:3001", - "http://localhost:3002", - "http://localhost:3003", - }, - ModifyRequest: func(c fiber.Ctx) error { - c.Request().Header.Add("X-Real-IP", c.IP()) - return nil - }, - ModifyResponse: func(c fiber.Ctx) error { - c.Response().Header.Del(fiber.HeaderServer) - return nil - }, -})) - -// Or this way if the balancer is using https and the destination server is only using http. -app.Use(proxy.BalancerForward([]string{ - "http://localhost:3001", - "http://localhost:3002", - "http://localhost:3003", -})) - - -// Make round robin balancer with IPv6 support. -app.Use(proxy.Balancer(proxy.Config{ - Servers: []string{ - "http://[::1]:3001", - "http://127.0.0.1:3002", - "http://localhost:3003", - }, - // Enable TCP4 and TCP6 network stacks. - DialDualStack: true, -})) -``` - -## Config - -| Property | Type | Description | Default | -|:----------------|:-----------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Servers | `[]string` | Servers defines a list of `://` HTTP servers, which are used in a round-robin manner. i.e.: "https://foobar.com, http://www.foobar.com" | (Required) | -| ModifyRequest | `fiber.Handler` | ModifyRequest allows you to alter the request. | `nil` | -| ModifyResponse | `fiber.Handler` | ModifyResponse allows you to alter the response. | `nil` | -| Timeout | `time.Duration` | Timeout is the request timeout used when calling the proxy client. | 1 second | -| ReadBufferSize | `int` | Per-connection buffer size for requests' reading. This also limits the maximum header size. Increase this buffer if your clients send multi-KB RequestURIs and/or multi-KB headers (for example, BIG cookies). | (Not specified) | -| WriteBufferSize | `int` | Per-connection buffer size for responses' writing. | (Not specified) | -| TlsConfig | `*tls.Config` (or `*fasthttp.TLSConfig` in v3) | TLS config for the HTTP client. | `nil` | -| DialDualStack | `bool` | Client will attempt to connect to both IPv4 and IPv6 host addresses if set to true. | `false` | -| Client | `*fasthttp.LBClient` | Client is a custom client when client config is complex. | `nil` | - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, - ModifyRequest: nil, - ModifyResponse: nil, - Timeout: fasthttp.DefaultLBClientTimeout, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/recover.md b/versioned_docs/version-v3.x/middleware/recover.md deleted file mode 100644 index 8d0a601eac0..00000000000 --- a/versioned_docs/version-v3.x/middleware/recover.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -id: recover ---- - -# Recover - -Recover middleware for [Fiber](https://github.com/gofiber/fiber) that recovers from panics anywhere in the stack chain and handles the control to the centralized [ErrorHandler](https://docs.gofiber.io/guide/error-handling). - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/recover" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use(recover.New()) - -// This panic will be caught by the middleware -app.Get("/", func(c fiber.Ctx) error { - panic("I'm an error") -}) -``` - -## Config - -| Property | Type | Description | Default | -|:------------------|:--------------------------------|:--------------------------------------------------------------------|:-------------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| EnableStackTrace | `bool` | EnableStackTrace enables handling stack trace. | `false` | -| StackTraceHandler | `func(fiber.Ctx, any)` | StackTraceHandler defines a function to handle stack trace. | defaultStackTraceHandler | - -## Default Config - -```go -var ConfigDefault = Config{ - Next: nil, - EnableStackTrace: false, - StackTraceHandler: defaultStackTraceHandler, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/redirect.md b/versioned_docs/version-v3.x/middleware/redirect.md deleted file mode 100644 index c7976a7a0cf..00000000000 --- a/versioned_docs/version-v3.x/middleware/redirect.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -id: redirect ---- - -# Redirect - -Redirection middleware for Fiber. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Examples - -```go -package main - -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/redirect" -) - -func main() { - app := fiber.New() - - app.Use(redirect.New(redirect.Config{ - Rules: map[string]string{ - "/old": "/new", - "/old/*": "/new/$1", - }, - StatusCode: 301, - })) - - app.Get("/new", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") - }) - app.Get("/new/*", func(c fiber.Ctx) error { - return c.SendString("Wildcard: " + c.Params("*")) - }) - - app.Listen(":3000") -} -``` - -**Test:** - -```curl -curl http://localhost:3000/old -curl http://localhost:3000/old/hello -``` - -## Config - -| Property | Type | Description | Default | -|:-----------|:------------------------|:---------------------------------------------------------------------------------------------------------------------------|:-----------------------| -| Next | `func(fiber.Ctx) bool` | Filter defines a function to skip middleware. | `nil` | -| Rules | `map[string]string` | Rules defines the URL path rewrite rules. The values captured in asterisk can be retrieved by index e.g. $1, $2 and so on. | Required | -| StatusCode | `int` | The status code when redirecting. This is ignored if Redirect is disabled. | 302 Temporary Redirect | - -## Default Config - -```go -var ConfigDefault = Config{ - StatusCode: fiber.StatusFound, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/requestid.md b/versioned_docs/version-v3.x/middleware/requestid.md deleted file mode 100644 index 36abb201912..00000000000 --- a/versioned_docs/version-v3.x/middleware/requestid.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: requestid ---- - -# RequestID - -RequestID middleware for [Fiber](https://github.com/gofiber/fiber) that adds an identifier to the response. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -func FromContext(c fiber.Ctx) string -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/requestid" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -app.Use(requestid.New()) - -// Or extend your config for customization -app.Use(requestid.New(requestid.Config{ - Header: "X-Custom-Header", - Generator: func() string { - return "static-id" - }, -})) -``` - -Getting the request ID - -```go -func handler(c fiber.Ctx) error { - id := requestid.FromContext(c) - log.Printf("Request ID: %s", id) - return c.SendString("Hello, World!") -} -``` - -## Config - -| Property | Type | Description | Default | -|:-----------|:------------------------|:--------------------------------------------------------------------------------------------------|:---------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Header | `string` | Header is the header key where to get/set the unique request ID. | "X-Request-ID" | -| Generator | `func() string` | Generator defines a function to generate the unique identifier. | utils.UUID | - -## Default Config -The default config uses a fast UUID generator which will expose the number of -requests made to the server. To conceal this value for better privacy, use the -`utils.UUIDv4` generator. - -```go -var ConfigDefault = Config{ - Next: nil, - Header: fiber.HeaderXRequestID, - Generator: utils.UUID, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/rewrite.md b/versioned_docs/version-v3.x/middleware/rewrite.md deleted file mode 100644 index d7ca4a223f4..00000000000 --- a/versioned_docs/version-v3.x/middleware/rewrite.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -id: rewrite ---- - -# Rewrite - -Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. - -## Signatures - -```go -func New(config ...Config) fiber.Handler -``` - -## Config - -| Property | Type | Description | Default | -|:---------|:------------------------|:-----------------------------------------------------------------------------------------------------|:-----------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip middleware. | `nil` | -| Rules | `map[string]string` | Rules defines the URL path rewrite rules. The values captured in asterisk can be retrieved by index. | (Required) | - -### Examples -```go -package main - -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/rewrite" -) - -func main() { - app := fiber.New() - - app.Use(rewrite.New(rewrite.Config{ - Rules: map[string]string{ - "/old": "/new", - "/old/*": "/new/$1", - }, - })) - - app.Get("/new", func(c fiber.Ctx) error { - return c.SendString("Hello, World!") - }) - app.Get("/new/*", func(c fiber.Ctx) error { - return c.SendString("Wildcard: " + c.Params("*")) - }) - - app.Listen(":3000") -} - -``` - -**Test:** - -```curl -curl http://localhost:3000/old -curl http://localhost:3000/old/hello -``` diff --git a/versioned_docs/version-v3.x/middleware/session.md b/versioned_docs/version-v3.x/middleware/session.md deleted file mode 100644 index db62b53cd47..00000000000 --- a/versioned_docs/version-v3.x/middleware/session.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: session ---- - -# Session - -Session middleware for [Fiber](https://github.com/gofiber/fiber). - -:::note -This middleware uses our [Storage](https://github.com/gofiber/storage) package to support various databases through a single interface. The default configuration for this middleware saves data to memory, see the examples below for other databases. -::: - -## Signatures - -```go -func New(config ...Config) *Store -func (s *Store) RegisterType(i any) -func (s *Store) Get(c fiber.Ctx) (*Session, error) -func (s *Store) Delete(id string) error -func (s *Store) Reset() error - -func (s *Session) Get(key string) any -func (s *Session) Set(key string, val any) -func (s *Session) Delete(key string) -func (s *Session) Destroy() error -func (s *Session) Reset() error -func (s *Session) Regenerate() error -func (s *Session) Save() error -func (s *Session) Fresh() bool -func (s *Session) ID() string -func (s *Session) Keys() []string -func (s *Session) SetExpiry(exp time.Duration) -``` - -:::caution -Storing `any` values are limited to built-ins Go types. -::: - -## Examples -Import the middleware package that is part of the Fiber web framework -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/session" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -// Initialize default config -// This stores all of your app's sessions -store := session.New() - -app.Get("/", func(c fiber.Ctx) error { - // Get session from storage - sess, err := store.Get(c) - if err != nil { - panic(err) - } - - // Get value - name := sess.Get("name") - - // Set key/value - sess.Set("name", "john") - - // Get all Keys - keys := sess.Keys() - - // Delete key - sess.Delete("name") - - // Destroy session - if err := sess.Destroy(); err != nil { - panic(err) - } - - // Sets a specific expiration for this session - sess.SetExpiry(time.Second * 2) - - // Save session - if err := sess.Save(); err != nil { - panic(err) - } - - return c.SendString(fmt.Sprintf("Welcome %v", name)) -}) -``` - -## Config - -| Property | Type | Description | Default | -|:------------------------|:----------------|:------------------------------------------------------------------------------------------------------------|:----------------------| -| Expiration | `time.Duration` | Allowed session duration. | `24 * time.Hour` | -| Storage | `fiber.Storage` | Storage interface to store the session data. | `memory.New()` | -| KeyLookup | `string` | KeyLookup is a string in the form of "`:`" that is used to extract session id from the request. | `"cookie:session_id"` | -| CookieDomain | `string` | Domain of the cookie. | `""` | -| CookiePath | `string` | Path of the cookie. | `""` | -| CookieSecure | `bool` | Indicates if cookie is secure. | `false` | -| CookieHTTPOnly | `bool` | Indicates if cookie is HTTP only. | `false` | -| CookieSameSite | `string` | Value of SameSite cookie. | `"Lax"` | -| CookieSessionOnly | `bool` | Decides whether cookie should last for only the browser session. Ignores Expiration if set to true. | `false` | -| KeyGenerator | `func() string` | KeyGenerator generates the session key. | `utils.UUIDv4` | -| CookieName (Deprecated) | `string` | Deprecated: Please use KeyLookup. The session name. | `""` | - -## Default Config - -```go -var ConfigDefault = Config{ - Expiration: 24 * time.Hour, - KeyLookup: "cookie:session_id", - KeyGenerator: utils.UUIDv4, - source: "cookie", - sessionName: "session_id", -} -``` - -## Constants - -```go -const ( - SourceCookie Source = "cookie" - SourceHeader Source = "header" - SourceURLQuery Source = "query" -) -``` - -### Custom Storage/Database - -You can use any storage from our [storage](https://github.com/gofiber/storage/) package. - -```go -storage := sqlite3.New() // From github.com/gofiber/storage/sqlite3 -store := session.New(session.Config{ - Storage: storage, -}) -``` - -To use the store, see the [Examples](#examples). diff --git a/versioned_docs/version-v3.x/middleware/skip.md b/versioned_docs/version-v3.x/middleware/skip.md deleted file mode 100644 index 07df603bc9f..00000000000 --- a/versioned_docs/version-v3.x/middleware/skip.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -id: skip ---- - -# Skip - -Skip middleware for [Fiber](https://github.com/gofiber/fiber) that skips a wrapped handler if a predicate is true. - -## Signatures -```go -func New(handler fiber.Handler, exclude func(c fiber.Ctx) bool) fiber.Handler -``` - -## Examples -Import the middleware package that is part of the Fiber web framework -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/skip" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -func main() { - app := fiber.New() - - app.Use(skip.New(BasicHandler, func(ctx fiber.Ctx) bool { - return ctx.Method() == fiber.MethodGet - })) - - app.Get("/", func(ctx fiber.Ctx) error { - return ctx.SendString("It was a GET request!") - }) - - log.Fatal(app.Listen(":3000")) -} - -func BasicHandler(ctx fiber.Ctx) error { - return ctx.SendString("It was not a GET request!") -} -``` - -:::tip -app.Use will handle requests from any route, and any method. In the example above, it will only skip if the method is GET. -::: diff --git a/versioned_docs/version-v3.x/middleware/static.md b/versioned_docs/version-v3.x/middleware/static.md deleted file mode 100644 index 6dd4e3cfe64..00000000000 --- a/versioned_docs/version-v3.x/middleware/static.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -id: static ---- - -# Static - -Static middleware for Fiber that serves static files such as **images**, **CSS,** and **JavaScript**. - -:::info -By default, **Static** will serve `index.html` files in response to a request on a directory. You can change it from [Config](#config)` -::: - -## Signatures - -```go -func New(root string, cfg ...Config) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the [Fiber](https://github.com/gofiber/fiber) web framework -```go -import( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/static" -) -``` - -### Serving files from a directory - -```go -app.Get("/*", static.New("./public")) -``` - -
-Test - -```sh -curl http://localhost:3000/hello.html -curl http://localhost:3000/css/style.css -``` - -
- -### Serving files from a directory with Use - -```go -app.Use("/", static.New("./public")) -``` - -
-Test - -```sh -curl http://localhost:3000/hello.html -curl http://localhost:3000/css/style.css -``` - -
- -### Serving a file - -```go -app.Use("/static", static.New("./public/hello.html")) -``` - -
-Test - -```sh -curl http://localhost:3000/static # will show hello.html -curl http://localhost:3000/static/john/doee # will show hello.html -``` - -
- -### Serving files using os.DirFS - -```go -app.Get("/files*", static.New("", static.Config{ - FS: os.DirFS("files"), - Browse: true, -})) -``` - -
-Test - -```sh -curl http://localhost:3000/files/css/style.css -curl http://localhost:3000/files/index.html -``` - -
- -### Serving files using embed.FS - -```go -//go:embed path/to/files -var myfiles embed.FS - -app.Get("/files*", static.New("", static.Config{ - FS: myfiles, - Browse: true, -})) -``` - -
-Test - -```sh -curl http://localhost:3000/files/css/style.css -curl http://localhost:3000/files/index.html -``` - -
- -### SPA (Single Page Application) - -```go -app.Use("/web", static.New("", static.Config{ - FS: os.DirFS("dist"), -})) - -app.Get("/web*", func(c fiber.Ctx) error { - return c.SendFile("dist/index.html") -}) -``` - -
-Test - -```sh -curl http://localhost:3000/web/css/style.css -curl http://localhost:3000/web/index.html -curl http://localhost:3000/web -``` - -
- -:::caution -To define static routes using `Get`, append the wildcard (`*`) operator at the end of the route. -::: - -## Config - -| Property | Type | Description | Default | -|:-----------|:------------------------|:---------------------------------------------------------------------------------------------------------------------------|:-----------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| FS | `fs.FS` | FS is the file system to serve the static files from.

You can use interfaces compatible with fs.FS like embed.FS, os.DirFS etc. | `nil` | -| Compress | `bool` | When set to true, the server tries minimizing CPU usage by caching compressed files. The middleware will compress the response using `gzip`, `brotli`, or `zstd` compression depending on the [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.

This works differently than the github.com/gofiber/compression middleware. | `false` | -| ByteRange | `bool` | When set to true, enables byte range requests. | `false` | -| Browse | `bool` | When set to true, enables directory browsing. | `false` | -| Download | `bool` | When set to true, enables direct download. | `false` | -| IndexNames | `[]string` | The names of the index files for serving a directory. | `[]string{"index.html"}` | -| CacheDuration | `string` | Expiration duration for inactive file handlers.

Use a negative time.Duration to disable it. | `10 * time.Second` | -| MaxAge | `int` | The value for the Cache-Control HTTP-header that is set on the file response. MaxAge is defined in seconds. | `0` | -| ModifyResponse | `fiber.Handler` | ModifyResponse defines a function that allows you to alter the response. | `nil` | -| NotFoundHandler | `fiber.Handler` | NotFoundHandler defines a function to handle when the path is not found. | `nil` | - -:::info -You can set `CacheDuration` config property to `-1` to disable caching. -::: - -## Default Config - -```go -var ConfigDefault = Config{ - Index: []string{"index.html"}, - CacheDuration: 10 * time.Second, -} -``` diff --git a/versioned_docs/version-v3.x/middleware/timeout.md b/versioned_docs/version-v3.x/middleware/timeout.md deleted file mode 100644 index e5f77546a0d..00000000000 --- a/versioned_docs/version-v3.x/middleware/timeout.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -id: timeout ---- - -# Timeout - -There exist two distinct implementations of timeout middleware [Fiber](https://github.com/gofiber/fiber). - -**New** - -As a `fiber.Handler` wrapper, it creates a context with `context.WithTimeout` and pass it in `UserContext`. - -If the context passed executions (eg. DB ops, Http calls) takes longer than the given duration to return, the timeout error is set and forwarded to the centralized `ErrorHandler`. - - -It does not cancel long running executions. Underlying executions must handle timeout by using `context.Context` parameter. - -## Signatures - -```go -func New(handler fiber.Handler, timeout time.Duration, timeoutErrors ...error) fiber.Handler -``` - -## Examples - -Import the middleware package that is part of the Fiber web framework - -```go -import ( - "github.com/gofiber/fiber/v3" - "github.com/gofiber/fiber/v3/middleware/timeout" -) -``` - -After you initiate your Fiber app, you can use the following possibilities: - -```go -func main() { - app := fiber.New() - h := func(c fiber.Ctx) error { - sleepTime, _ := time.ParseDuration(c.Params("sleepTime") + "ms") - if err := sleepWithContext(c.UserContext(), sleepTime); err != nil { - return fmt.Errorf("%w: execution error", err) - } - return nil - } - - app.Get("/foo/:sleepTime", timeout.New(h, 2*time.Second)) - log.Fatal(app.Listen(":3000")) -} - -func sleepWithContext(ctx context.Context, d time.Duration) error { - timer := time.NewTimer(d) - - select { - case <-ctx.Done(): - if !timer.Stop() { - <-timer.C - } - return context.DeadlineExceeded - case <-timer.C: - } - return nil -} -``` - -Test http 200 with curl: - -```bash -curl --location -I --request GET 'http://localhost:3000/foo/1000' -``` - -Test http 408 with curl: - -```bash -curl --location -I --request GET 'http://localhost:3000/foo/3000' -``` - -Use with custom error: - -```go -var ErrFooTimeOut = errors.New("foo context canceled") - -func main() { - app := fiber.New() - h := func(c fiber.Ctx) error { - sleepTime, _ := time.ParseDuration(c.Params("sleepTime") + "ms") - if err := sleepWithContextWithCustomError(c.UserContext(), sleepTime); err != nil { - return fmt.Errorf("%w: execution error", err) - } - return nil - } - - app.Get("/foo/:sleepTime", timeout.New(h, 2*time.Second, ErrFooTimeOut)) - log.Fatal(app.Listen(":3000")) -} - -func sleepWithContextWithCustomError(ctx context.Context, d time.Duration) error { - timer := time.NewTimer(d) - select { - case <-ctx.Done(): - if !timer.Stop() { - <-timer.C - } - return ErrFooTimeOut - case <-timer.C: - } - return nil -} -``` - -Sample usage with a DB call: - -```go -func main() { - app := fiber.New() - db, _ := gorm.Open(postgres.Open("postgres://localhost/foodb"), &gorm.Config{}) - - handler := func(ctx fiber.Ctx) error { - tran := db.WithContext(ctx.UserContext()).Begin() - - if tran = tran.Exec("SELECT pg_sleep(50)"); tran.Error != nil { - return tran.Error - } - - if tran = tran.Commit(); tran.Error != nil { - return tran.Error - } - - return nil - } - - app.Get("/foo", timeout.New(handler, 10*time.Second)) - log.Fatal(app.Listen(":3000")) -} -``` diff --git a/versioned_docs/version-v3.x/partials/routing/handler.md b/versioned_docs/version-v3.x/partials/routing/handler.md deleted file mode 100644 index 5cff828d4cc..00000000000 --- a/versioned_docs/version-v3.x/partials/routing/handler.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: route-handlers -title: Route Handlers ---- - -import Reference from '@site/src/components/reference'; - -Registers a route bound to a specific [HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods). - -```go title="Signatures" -// HTTP methods -func (app *App) Get(path string, handler Handler, middlewares ...Handler) Router -func (app *App) Head(path string, handler Handler, middlewares ...Handler) Router -func (app *App) Post(path string, handler Handler, middlewares ...Handler) Router -func (app *App) Put(path string, handler Handler, middlewares ...Handler) Router -func (app *App) Delete(path string, handler Handler, middlewares ...Handler) Router -func (app *App) Connect(path string, handler Handler, middlewares ...Handler) Router -func (app *App) Options(path string, handler Handler, middlewares ...Handler) Router -func (app *App) Trace(path string, handler Handler, middlewares ...Handler) Router -func (app *App) Patch(path string, handler Handler, middlewares ...Handler) Router - -// Add allows you to specify a method as value -func (app *App) Add(method, path string, handler Handler, middlewares ...Handler) Router - -// All will register the route on all HTTP methods -// Almost the same as app.Use but not bound to prefixes -func (app *App) All(path string, handler Handler, middlewares ...Handler) Router -``` - -```go title="Examples" -// Simple GET handler -app.Get("/api/list", func(c fiber.Ctx) error { - return c.SendString("I'm a GET request!") -}) - -// Simple POST handler -app.Post("/api/register", func(c fiber.Ctx) error { - return c.SendString("I'm a POST request!") -}) -``` - -**Use** - -Can be used for middleware packages and prefix catchers. These routes will only match the beginning of each path i.e. `/john` will match `/john/doe`, `/johnnnnn` etc - -```go title="Signature" -func (app *App) Use(args ...any) Router - -// Different usage variations -func (app *App) Use(handler Handler, middlewares ...Handler) Router -func (app *App) Use(path string, handler Handler, middlewares ...Handler) Router -func (app *App) Use(paths []string, handler Handler, middlewares ...Handler) Router -func (app *App) Use(path string, app *App) Router -``` - -```go title="Examples" -// Match any request -app.Use(func(c fiber.Ctx) error { - return c.Next() -}) - -// Match request starting with /api -app.Use("/api", func(c fiber.Ctx) error { - return c.Next() -}) - -// Match requests starting with /api or /home (multiple-prefix support) -app.Use([]string{"/api", "/home"}, func(c fiber.Ctx) error { - return c.Next() -}) - -// Attach multiple handlers -app.Use("/api", func(c fiber.Ctx) error { - c.Set("X-Custom-Header", random.String(32)) - return c.Next() -}, func(c fiber.Ctx) error { - return c.Next() -}) - -// Mount a sub-app -app.Use("/api", api) -``` diff --git a/versioned_docs/version-v3.x/whats_new.md b/versioned_docs/version-v3.x/whats_new.md deleted file mode 100644 index c34ed4bf7b6..00000000000 --- a/versioned_docs/version-v3.x/whats_new.md +++ /dev/null @@ -1,447 +0,0 @@ ---- -id: whats_new -title: πŸ†• Whats New in v3 -sidebar_position: 2 -toc_max_heading_level: 3 ---- - -:::caution - -Its a draft, not finished yet. - -::: - -[//]: # (https://github.com/gofiber/fiber/releases/tag/v3.0.0-beta.2) - -## πŸŽ‰ Welcome - -We are excited to announce the release of Fiber v3! πŸš€ - -In this guide, we'll walk you through the most important changes in Fiber `v3` and show you how to migrate your existing Fiber `v2` applications to Fiber `v3`. - -Here's a quick overview of the changes in Fiber `v3`: -- [πŸš€ App](#-app) -- [πŸ—ΊοΈ Router](#-router) -- [🧠 Context](#-context) -- [πŸ“Ž Binding](#-binding) -- [πŸ”„οΈ Redirect](#-redirect) -- [🌎 Client package](#-client-package) -- [🧰 Generic functions](#-generic-functions) -- [🧬 Middlewares](#-middlewares) - - [CORS](#cors) - - [Session](#session) - - [Filesystem](#filesystem) - - [Monitor](#monitor) -- [πŸ“‹ Migration guide](#-migration-guide) - -## Drop for old Go versions - -Fiber `v3` drops support for Go versions below `1.21`. We recommend upgrading to Go `1.21` or higher to use Fiber `v3`. - -## πŸš€ App - -:::caution -DRAFT section -::: - -We have made several changes to the Fiber app, including: - -* Listen -> unified with config -* Static -> has been removed and moved to [static middleware](./middleware/static.md) -* app.Config properties moved to listen config - * DisableStartupMessage - * EnablePrefork -> previously Prefork - * EnablePrintRoutes - * ListenerNetwork -> previously Network - -### new methods - -* RegisterCustomBinder -* RegisterCustomConstraint -* NewCtxFunc - -### removed methods - -* Mount -> Use app.Use() instead -* ListenTLS -> Use app.Listen() with tls.Config -* ListenTLSWithCertificate -> Use app.Listen() with tls.Config -* ListenMutualTLS -> Use app.Listen() with tls.Config -* ListenMutualTLSWithCertificate -> Use app.Listen() with tls.Config - -### Methods changes - -* Test -> timeout changed to 1 second -* Listen -> has a config parameter -* Listener -> has a config parameter - -### CTX interface + customizable - ---- - -## πŸ—Ί Router - -We have slightly adapted our router interface - -### HTTP method registration - -In `v2` one handler was already mandatory when the route has been registered, but this was checked at runtime and was not correctly reflected in the signature, this has now been changed in `v3` to make it more explicit. - -```diff -- Get(path string, handlers ...Handler) Router -+ Get(path string, handler Handler, middleware ...Handler) Router -- Head(path string, handlers ...Handler) Router -+ Head(path string, handler Handler, middleware ...Handler) Router -- Post(path string, handlers ...Handler) Router -+ Post(path string, handler Handler, middleware ...Handler) Router -- Put(path string, handlers ...Handler) Router -+ Put(path string, handler Handler, middleware ...Handler) Router -- Delete(path string, handlers ...Handler) Router -+ Delete(path string, handler Handler, middleware ...Handler) Router -- Connect(path string, handlers ...Handler) Router -+ Connect(path string, handler Handler, middleware ...Handler) Router -- Options(path string, handlers ...Handler) Router -+ Options(path string, handler Handler, middleware ...Handler) Router -- Trace(path string, handlers ...Handler) Router -+ Trace(path string, handler Handler, middleware ...Handler) Router -- Patch(path string, handlers ...Handler) Router -+ Patch(path string, handler Handler, middleware ...Handler) Router -- All(path string, handlers ...Handler) Router -+ All(path string, handler Handler, middleware ...Handler) Router -``` - -### Route chaining - -The route method is now like [`Express`](https://expressjs.com/de/api.html#app.route) which gives you the option of a different notation and allows you to concatenate the route declaration. - -```diff -- Route(prefix string, fn func(router Router), name ...string) Router -+ Route(path string) Register -``` - -
-Example - -```go -app.Route("/api").Route("/user/:id?") - .Get(func(c fiber.Ctx) error { - // Get user - return c.JSON(fiber.Map{"message": "Get user", "id": c.Params("id")}) - }) - .Post(func(c fiber.Ctx) error { - // Create user - return c.JSON(fiber.Map{"message": "User created"}) - }) - .Put(func(c fiber.Ctx) error { - // Update user - return c.JSON(fiber.Map{"message": "User updated", "id": c.Params("id")}) - }) - .Delete(func(c fiber.Ctx) error { - // Delete user - return c.JSON(fiber.Map{"message": "User deleted", "id": c.Params("id")}) - }) -}) -``` -
- -[Here](./api/app#route) you can find more information. - -### Middleware registration - -We have aligned our method for middlewares closer to [`Express`](https://expressjs.com/de/api.html#app.use) and now also support the [`Use`](./api/app#use) of multiple prefixes. - -Registering a subapp is now also possible via the [`Use`](./api/app#use) method instead of the old `app.Mount` method. - -
-Example - -```go -// register mulitple prefixes -app.Use(["/v1", "/v2"], func(c *fiber.Ctx) error { - // Middleware for /v1 and /v2 - return c.Next() -}) - -// define subapp -api := fiber.New() -api.Get("/user", func(c *fiber.Ctx) error { - return c.SendString("User") -}) -// register subapp -app.Use("/api", api) -``` -
- -To enable the routing changes above we had to slightly adjust the signature of the `Add` method. - -```diff -- Add(method, path string, handlers ...Handler) Router -+ Add(methods []string, path string, handler Handler, middleware ...Handler) Router -``` - ---- - -## 🧠 Context - -:::caution -DRAFT section -::: - -### New Features - -- Cookie now allows Partitioned cookies for [CHIPS](https://developers.google.com/privacy-sandbox/3pcd/chips) support. CHIPS (Cookies Having Independent Partitioned State) is a feature that improves privacy by allowing cookies to be partitioned by top-level site, mitigating cross-site tracking. - -### new methods - -* AutoFormat -> ExpressJs like -* Host -> ExpressJs like -* Port -> ExpressJs like -* IsProxyTrusted -* Reset -* Schema -> ExpressJs like -* SendStream -> ExpressJs like -* SendString -> ExpressJs like -* String -> ExpressJs like -* ViewBind -> instead of Bind - -### removed methods - -* AllParams -> c.Bind().URL() ? -* ParamsInt -> Params Generic -* QueryBool -> Query Generic -* QueryFloat -> Query Generic -* QueryInt -> Query Generic -* BodyParser -> c.Bind().Body() -* CookieParser -> c.Bind().Cookie() -* ParamsParser -> c.Bind().URL() -* RedirectToRoute -> c.Redirect().Route() -* RedirectBack -> c.Redirect().Back() -* ReqHeaderParser -> c.Bind().Header() - -### changed methods - -* Bind -> for Binding instead of View, us c.ViewBind() -* Format -> Param: body interface{} -> handlers ...ResFmt -* Redirect -> c.Redirect().To() -* SendFile now supports different configurations using the config parameter. - ---- - -## 🌎 Client package - -The Gofiber client has been completely rebuilt. It includes numerous new features such as Cookiejar, request/response hooks, and more. -You can take a look to [client docs](./client/rest.md) to see what's new with the client. - -## πŸ“Ž Binding - -:::caution -DRAFT section -::: - -## πŸ”„ Redirect - -:::caution -DRAFT section -::: - - -## 🧰 Generic functions - -:::caution -DRAFT section -::: - -## 🧬 Middlewares - -### Cache - -We are excited to introduce a new option in our caching middleware: Cache Invalidator. This feature provides greater control over cache management, allowing you to define a custom conditions for invalidating cache entries. - -### CORS - -We've made some changes to the CORS middleware to improve its functionality and flexibility. Here's what's new: - -#### New Struct Fields -- `Config.AllowPrivateNetwork`: This new field is a boolean that allows you to control whether private networks are allowed. This is related to the [Private Network Access (PNA)](https://wicg.github.io/private-network-access/) specification from the Web Incubator Community Group (WICG). When set to `true`, the CORS middleware will allow CORS preflight requests from private networks and respond with the `Access-Control-Allow-Private-Network: true` header. This could be useful in development environments or specific use cases, but should be done with caution due to potential security risks. - -#### Updated Struct Fields -We've updated several fields from a single string (containing comma-separated values) to slices, allowing for more explicit declaration of multiple values. Here are the updated fields: - -- `Config.AllowOrigins`: Now accepts a slice of strings, each representing an allowed origin. -- `Config.AllowMethods`: Now accepts a slice of strings, each representing an allowed method. -- `Config.AllowHeaders`: Now accepts a slice of strings, each representing an allowed header. -- `Config.ExposeHeaders`: Now accepts a slice of strings, each representing an exposed header. - -### Compression - -We've added support for `zstd` compression on top of `gzip`, `deflate`, and `brotli`. - -### Session - -:::caution -DRAFT section -::: - -### Filesystem - -We've decided to remove filesystem middleware to clear up the confusion between static and filesystem middleware. -Now, static middleware can do everything that filesystem middleware and static do. You can check out [static middleware](./middleware/static.md) or [migration guide](#-migration-guide) to see what has been changed. - -### Monitor - -:::caution -DRAFT section -::: - -Monitor middleware is now in Contrib package. - -## πŸ“‹ Migration guide - -- [πŸš€ App](#-app-1) -- [πŸ—Ί Router](#-router-1) -- [🧠 Context](#-context-1) -- [πŸ“Ž Parser](#-parser) -- [πŸ”„ Redirect](#-redirect-1) -- [🌎 Client package](#-client-package-1) -- [🧬 Middlewares](#-middlewares-1) - - -### πŸš€ App - -#### Static - -Since we've removed `app.Static()`, you need to move methods to static middleware like the example below: - -```go -// Before -app.Static("/", "./public") -app.Static("/prefix", "./public") -app.Static("/prefix", "./public", Static{ - Index: "index.htm", -}) -app.Static("*", "./public/index.html") -``` - -```go -// After -app.Get("/*", static.New("./public")) -app.Get("/prefix*", static.New("./public")) -app.Get("/prefix*", static.New("./public", static.Config{ - IndexNames: []string{"index.htm", "index.html"}, -})) -app.Get("*", static.New("./public/index.html")) -``` - -:::caution -You have to put `*` to the end of the route if you don't define static route with `app.Use`. -::: - -### πŸ—Ί Router - -The signatures for [`Add`](#middleware-registration) and [`Route`](#route-chaining) have been changed. - -To migrate [`Add`](#middleware-registration) you must change the `methods` in a slice. - -```go -// Before -app.Add(fiber.MethodPost, "/api", myHandler) -``` - -```go -// After -app.Add([]string{fiber.MethodPost}, "/api", myHandler) -``` - -To migrate [`Route`](#route-chaining) you need to read [this](#route-chaining). - -```go -// Before -app.Route("/api", func(apiGrp Router) { - apiGrp.Route("/user/:id?", func(userGrp Router) { - userGrp.Get("/", func(c fiber.Ctx) error { - // Get user - return c.JSON(fiber.Map{"message": "Get user", "id": c.Params("id")}) - }) - userGrp.Post("/", func(c fiber.Ctx) error { - // Create user - return c.JSON(fiber.Map{"message": "User created"}) - }) - }) -}) -``` - -```go -// After -app.Route("/api").Route("/user/:id?") - .Get(func(c fiber.Ctx) error { - // Get user - return c.JSON(fiber.Map{"message": "Get user", "id": c.Params("id")}) - }) - .Post(func(c fiber.Ctx) error { - // Create user - return c.JSON(fiber.Map{"message": "User created"}) - }); -``` - -### 🧠 Context - -### πŸ“Ž Parser - -### πŸ”„ Redirect - -### 🌎 Client package - -### 🧬 Middlewares - -#### CORS - -The CORS middleware has been updated to use slices instead of strings for the `AllowOrigins`, `AllowMethods`, `AllowHeaders`, and `ExposeHeaders` fields. Here's how you can update your code: - -```go -// Before -app.Use(cors.New(cors.Config{ - AllowOrigins: "https://example.com,https://example2.com", - AllowMethods: strings.Join([]string{fiber.MethodGet, fiber.MethodPost}, ","), - AllowHeaders: "Content-Type", - ExposeHeaders: "Content-Length", -})) - -// After -app.Use(cors.New(cors.Config{ - AllowOrigins: []string{"https://example.com", "https://example2.com"}, - AllowMethods: []string{fiber.MethodGet, fiber.MethodPost}, - AllowHeaders: []string{"Content-Type"}, - ExposeHeaders: []string{"Content-Length"}, -})) -``` - -#### Filesystem - -You need to move filesystem middleware to static middleware due to it has been removed from the core. - -```go -// Before -app.Use(filesystem.New(filesystem.Config{ - Root: http.Dir("./assets"), -})) - -app.Use(filesystem.New(filesystem.Config{ - Root: http.Dir("./assets"), - Browse: true, - Index: "index.html", - MaxAge: 3600, -})) -``` - -```go -// After -app.Use(static.New("", static.Config{ - FS: os.DirFS("./assets"), -})) - -app.Use(static.New("", static.Config{ - FS: os.DirFS("./assets"), - Browse: true, - IndexNames: []string{"index.html"}, - MaxAge: 3600, -})) -``` diff --git a/versioned_sidebars/version-v3.x-sidebars.json b/versioned_sidebars/version-v3.x-sidebars.json deleted file mode 100644 index caea0c03ba6..00000000000 --- a/versioned_sidebars/version-v3.x-sidebars.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "tutorialSidebar": [ - { - "type": "autogenerated", - "dirName": "." - } - ] -} diff --git a/versions.json b/versions.json index 83719825d58..616eee8adc8 100644 --- a/versions.json +++ b/versions.json @@ -1,5 +1,4 @@ [ - "v3.x", "v2.x", "v1.x" ]