mirror of
https://github.com/gofiber/fiber.git
synced 2025-05-31 11:52:41 +00:00
* Add support for consistent documentation using markdownlint * Only run workflow during changes to markdown files * Fix more inconsistencies * Fixes to markdown under .github/ * More fixes * Apply suggestions from code review Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Fix typo in limiter docs * Add missing space before code-block * Add check for dead-links * Add write-good * Remove legacy README files * Fix glob for skipping .md files * Use paths-ignore instead --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
209 lines
5.2 KiB
Markdown
209 lines
5.2 KiB
Markdown
# Fiber Binders
|
|
|
|
Binder is a new request/response binding feature for Fiber. Against the old Fiber parsers, it supports custom binder registration, struct validation, `map[string]string`, `map[string][]string`, and more. It's introduced in Fiber v3 and a replacement of:
|
|
|
|
- BodyParser
|
|
- ParamsParser
|
|
- GetReqHeaders
|
|
- GetRespHeaders
|
|
- AllParams
|
|
- QueryParser
|
|
- ReqHeaderParser
|
|
|
|
## Default Binders
|
|
|
|
- [Form](form.go)
|
|
- [Query](query.go)
|
|
- [URI](uri.go)
|
|
- [Header](header.go)
|
|
- [Response Header](resp_header.go)
|
|
- [Cookie](cookie.go)
|
|
- [JSON](json.go)
|
|
- [XML](xml.go)
|
|
|
|
## Guides
|
|
|
|
### Binding into the Struct
|
|
|
|
Fiber supports binding into the struct with [gorilla/schema](https://github.com/gorilla/schema). Here's an example:
|
|
|
|
```go
|
|
// 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 "<login><name>john</name><pass>doe</pass></login>" 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"
|
|
```
|
|
|
|
### Binding into the Map
|
|
|
|
Fiber supports binding into the `map[string]string` or `map[string][]string`. Here's an example:
|
|
|
|
```go
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
p := make(map[string][]string)
|
|
|
|
if err := c.Bind().Query(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/?name=john&pass=doe&products=shoe,hat"
|
|
```
|
|
|
|
### Behaviors of Should/Must
|
|
|
|
Normally, Fiber returns binder error directly. However; if you want to handle it automatically, you can prefer `Must()`.
|
|
|
|
If there's an error it'll return error and 400 as HTTP status. Here's an example for it:
|
|
|
|
```go
|
|
// Field names should start with an uppercase letter
|
|
type Person struct {
|
|
Name string `json:"name,required"`
|
|
Pass string `json:"pass"`
|
|
}
|
|
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
p := new(Person)
|
|
|
|
if err := c.Bind().Must().JSON(p); err != nil {
|
|
return err
|
|
// Status code: 400
|
|
// Response: Bad request: name is empty
|
|
}
|
|
|
|
// ...
|
|
})
|
|
|
|
// Run tests with the following curl command:
|
|
|
|
// curl -X GET -H "Content-Type: application/json" --data "{\"pass\":\"doe\"}" localhost:3000
|
|
```
|
|
|
|
### Defining Custom Binder
|
|
|
|
We didn't add much binder to make Fiber codebase minimal. If you want to use your own binders, it's easy to register and use them. Here's an example for TOML binder.
|
|
|
|
```go
|
|
type Person struct {
|
|
Name string `toml:"name"`
|
|
Pass string `toml:"pass"`
|
|
}
|
|
|
|
type tomlBinding struct{}
|
|
|
|
func (b *tomlBinding) Name() string {
|
|
return "toml"
|
|
}
|
|
|
|
func (b *tomlBinding) MIMETypes() []string {
|
|
return []string{"application/toml"}
|
|
}
|
|
|
|
func (b *tomlBinding) Parse(c fiber.Ctx, out any) error {
|
|
return toml.Unmarshal(c.Body(), out)
|
|
}
|
|
|
|
func main() {
|
|
app := fiber.New()
|
|
app.RegisterCustomBinder(&tomlBinding{})
|
|
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
out := new(Person)
|
|
if err := c.Bind().Body(out); err != nil {
|
|
return err
|
|
}
|
|
|
|
// or you can use like:
|
|
// if err := c.Bind().Custom("toml", out); err != nil {
|
|
// return err
|
|
// }
|
|
|
|
return c.SendString(out.Pass) // test
|
|
})
|
|
|
|
app.Listen(":3000")
|
|
}
|
|
|
|
// curl -X GET -H "Content-Type: application/toml" --data "name = 'bar'
|
|
// pass = 'test'" localhost:3000
|
|
```
|
|
|
|
### Defining Custom Validator
|
|
|
|
All Fiber binders supporting struct validation if you defined validator inside of the config. You can create own validator, or use [go-playground/validator](https://github.com/go-playground/validator), [go-ozzo/ozzo-validation](https://github.com/go-ozzo/ozzo-validation)... Here's an example of simple custom validator:
|
|
|
|
```go
|
|
type Query struct {
|
|
Name string `query:"name"`
|
|
}
|
|
|
|
type structValidator struct{}
|
|
|
|
func (v *structValidator) Engine() any {
|
|
return ""
|
|
}
|
|
|
|
func (v *structValidator) ValidateStruct(out any) error {
|
|
out = reflect.ValueOf(out).Elem().Interface()
|
|
sq := out.(Query)
|
|
|
|
if sq.Name != "john" {
|
|
return errors.New("you should have entered right name!")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
app := fiber.New(fiber.Config{StructValidator: &structValidator{}})
|
|
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
out := new(Query)
|
|
if err := c.Bind().Query(out); err != nil {
|
|
return err // you should have entered right name!
|
|
}
|
|
return c.SendString(out.Name)
|
|
})
|
|
|
|
app.Listen(":3000")
|
|
}
|
|
|
|
// Run tests with the following curl command:
|
|
|
|
// curl "http://localhost:3000/?name=efe"
|
|
```
|