add a table on the README for the param types, macro funcs and do it yourself section

Former-commit-id: eca9418779371c014d3bf3bca88430055841da4f
This commit is contained in:
Gerasimos (Makis) Maropoulos 2018-08-24 14:41:53 +03:00
parent cbd8fe95ac
commit b3bc30c5af
3 changed files with 145 additions and 8 deletions

101
README.md
View File

@ -135,6 +135,107 @@ func main() {
### Parameters in path
| Param Type | Go Type | Validation | Retrieve Helper |
| -----------------|------|-------------|------|
| `:string` | string | anything | `Params().Get` |
| `:number` | uint, uint8, uint16, uint32, uint64, int, int8, int32, int64 | positive or negative number, any number of digits | `Params().GetInt/Int64`...|
| `:int64` | int64 | -9223372036854775808 to 9223372036854775807 | `Params().GetInt64` |
| `:uint8` | uint8 | 0 to 255 | `Params().GetUint8` |
| `:uint64` | uint64 | 0 to 18446744073709551615 | `Params().GetUint64` |
| `:bool` | bool | "1" or "t" or "T" or "TRUE" or "true" or "True" or "0" or "f" or "F" or "FALSE" or "false" or "False" | `Params().GetBool` |
| `:alphabetical` | string | lowercase or uppercase letters | `Params().Get` |
| `:file` | string | lowercase or uppercase letters, numbers, underscore (_), dash (-), point (.) and no spaces or other special characters that are not valid for filenames | `Params().Get` |
| `:path` | string | anything, can be separated by slashes (path segments) but should be the last part of the route path | `Params().Get` |
**Usage**:
```go
app.Get("/users/{id:uint64}", func(ctx iris.Context){
id, _ := ctx.Params().GetUint64("id")
// [...]
})
```
| Built'n Func | Param Types |
| -----------|---------------|
| `regexp`(expr string) | :string |
| `prefix`(prefix string) | :string |
| `suffix`(suffix string) | :string |
| `contains`(s string) | :string |
| `min`(minValue int or int8 or int16 or int32 or int64 or uint8 or uint16 or uint32 or uint64 or float32 or float64) | :string(char length), :number, :int64, :uint8, :uint64 |
| `max`(maxValue int or int8 or int16 or int32 or int64 or uint8 or uint16 or uint32 or uint64 or float32 or float64) | :string(char length), :number, :int64, :uint8, :uint64 |
| `range`(minValue, maxValue int or int8 or int16 or int32 or int64 or uint8 or uint16 or uint32 or uint64 or float32 or float64) | :number, :int64, :uint8, :uint64 |
**Usage**:
```go
app.Get("/profile/{name:alphabetical max(255)}", func(ctx iris.Context){
name := ctx.Params().Get("name")
// len(name) <=255 otherwise this route will fire 404 Not Found
// and this handler will not be executed at all.
})
```
**Do It Yourself**:
The `RegisterFunc` can accept any function that returns a `func(paramValue string) bool`.
Or just a `func(string) bool`.
If the validation fails then it will fire `404` or whatever status code the `else` keyword has.
```go
latLonExpr := "^-?[0-9]{1,3}(?:\\.[0-9]{1,10})?$"
latLonRegex, _ := regexp.Compile(latLonExpr)
// Register your custom argument-less macro function to the :string param type.
// MatchString is a type of func(string) bool, so we use it as it is.
app.Macros().String.RegisterFunc("coordinate", latLonRegex.MatchString)
app.Get("/coordinates/{lat:string coordinate() else 400}/{lon:string coordinate() else 400}", func(ctx iris.Context) {
ctx.Writef("Lat: %s | Lon: %s", ctx.Params().Get("lat"), ctx.Params().Get("lon"))
})
```
Register your custom macro function which accepts two int arguments.
```go
app.Macros().String.RegisterFunc("range", func(minLength, maxLength int) func(string) bool {
return func(paramValue string) bool {
return len(paramValue) >= minLength && len(paramValue) <= maxLength
}
})
app.Get("/limitchar/{name:string range(1,200)}", func(ctx iris.Context) {
name := ctx.Params().Get("name")
ctx.Writef(`Hello %s | the name should be between 1 and 200 characters length
otherwise this handler will not be executed`, name)
})
```
Register your custom macro function which accepts a slice of strings `[...,...]`.
```go
app.Macros().String.RegisterFunc("has", func(validNames []string) func(string) bool {
return func(paramValue string) bool {
for _, validName := range validNames {
if validName == paramValue {
return true
}
}
return false
}
})
app.Get("/static_validation/{name:string has([kataras,gerasimos,maropoulos]}", func(ctx iris.Context) {
name := ctx.Params().Get("name")
ctx.Writef(`Hello %s | the name should be "kataras" or "gerasimos" or "maropoulos"
otherwise this handler will not be executed`, name)
})
```
**Example Code**:
```go
func main() {
app := iris.Default()

View File

@ -159,17 +159,17 @@ func main() {
ctx.Writef("age selected: %d", age)
})
// Another example using a custom regexp and any custom logic.
// Another example using a custom regexp or any custom logic.
// Register your custom argument-less macro function to the :string param type.
latLonExpr := "^-?[0-9]{1,3}(?:\\.[0-9]{1,10})?$"
latLonRegex, err := regexp.Compile(latLonExpr)
if err != nil {
panic(err)
}
app.Macros().String.RegisterFunc("coordinate", func() func(paramName string) (ok bool) {
// MatchString is a type of func(string) bool, so we can return that as it's.
return latLonRegex.MatchString
})
// MatchString is a type of func(string) bool, so we use it as it is.
app.Macros().String.RegisterFunc("coordinate", latLonRegex.MatchString)
app.Get("/coordinates/{lat:string coordinate() else 502}/{lon:string coordinate() else 502}", func(ctx iris.Context) {
ctx.Writef("Lat: %s | Lon: %s", ctx.Params().Get("lat"), ctx.Params().Get("lon"))
@ -177,6 +177,42 @@ func main() {
//
// Another one is by using a custom body.
app.Macros().String.RegisterFunc("range", func(minLength, maxLength int) func(string) bool {
return func(paramValue string) bool {
return len(paramValue) >= minLength && len(paramValue) <= maxLength
}
})
app.Get("/limitchar/{name:string range(1,200)}", func(ctx iris.Context) {
name := ctx.Params().Get("name")
ctx.Writef(`Hello %s | the name should be between 1 and 200 characters length
otherwise this handler will not be executed`, name)
})
//
// Register your custom macro function which accepts a slice of strings `[...,...]`.
app.Macros().String.RegisterFunc("has", func(validNames []string) func(string) bool {
return func(paramValue string) bool {
for _, validName := range validNames {
if validName == paramValue {
return true
}
}
return false
}
})
app.Get("/static_validation/{name:string has([kataras,gerasimos,maropoulos]}", func(ctx iris.Context) {
name := ctx.Params().Get("name")
ctx.Writef(`Hello %s | the name should be "kataras" or "gerasimos" or "maropoulos"
otherwise this handler will not be executed`, name)
})
//
// http://localhost:8080/game/a-zA-Z/level/42
// remember, alphabetical is lowercase or uppercase letters only.
app.Get("/game/{name:alphabetical}/level/{level:number}", func(ctx iris.Context) {

View File

@ -367,7 +367,7 @@ func (c *testControllerRelPathFromFunc) EndRequest(ctx context.Context) {
func (c *testControllerRelPathFromFunc) Get() {}
func (c *testControllerRelPathFromFunc) GetBy(uint64) {}
func (c *testControllerRelPathFromFunc) GetUint8RatioBy(uint8) {}
func (c *testControllerRelPathFromFunc) GetUint64RatioBy(int64) {}
func (c *testControllerRelPathFromFunc) GetInt64RatioBy(int64) {}
func (c *testControllerRelPathFromFunc) GetAnythingByWildcard(string) {}
func (c *testControllerRelPathFromFunc) GetLogin() {}
@ -395,8 +395,8 @@ func TestControllerRelPathFromFunc(t *testing.T) {
e.GET("/uint8/ratio/255").Expect().Status(iris.StatusOK).
Body().Equal("GET:/uint8/ratio/255")
e.GET("/uint8/ratio/256").Expect().Status(iris.StatusNotFound)
e.GET("/uint64/ratio/-42").Expect().Status(iris.StatusOK).
Body().Equal("GET:/uint64/ratio/-42")
e.GET("/int64/ratio/-42").Expect().Status(iris.StatusOK).
Body().Equal("GET:/int64/ratio/-42")
e.GET("/something/true").Expect().Status(iris.StatusOK).
Body().Equal("GET:/something/true")
e.GET("/something/false").Expect().Status(iris.StatusOK).