mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
110 lines
3.9 KiB
Go
110 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/kataras/iris/v12"
|
|
"github.com/kataras/iris/v12/core/router"
|
|
)
|
|
|
|
/*
|
|
A Router should contain all three of the following methods:
|
|
- HandleRequest should handle the request based on the Context.
|
|
HandleRequest(ctx iris.Context)
|
|
- Build should builds the handler, it's being called on router's BuildRouter.
|
|
Build(provider router.RoutesProvider) error
|
|
- RouteExists reports whether a particular route exists.
|
|
RouteExists(ctx iris.Context, method, path string) bool
|
|
- FireErrorCode(ctx iris.Context) should handle the given ctx.GetStatusCode().
|
|
|
|
For a more detailed, complete and useful example
|
|
you can take a look at the iris' router itself which is located at:
|
|
https://github.com/kataras/iris/tree/master/core/router/handler.go
|
|
which completes this exact interface, the `router#RequestHandler`.
|
|
*/
|
|
type customRouter struct {
|
|
// a copy of routes (safer because you will not be able to alter a route on serve-time without a `app.RefreshRouter` call):
|
|
// []router.Route
|
|
// or just expect the whole routes provider:
|
|
provider router.RoutesProvider
|
|
}
|
|
|
|
// HandleRequest a silly example which finds routes based only on the first part of the requested path
|
|
// which must be a static one as well, the rest goes to fill the parameters.
|
|
func (r *customRouter) HandleRequest(ctx iris.Context) {
|
|
path := ctx.Path()
|
|
ctx.Application().Logger().Infof("Requested resource path: %s", path)
|
|
|
|
parts := strings.Split(path, "/")[1:]
|
|
staticPath := "/" + parts[0]
|
|
for _, route := range r.provider.GetRoutes() {
|
|
if strings.HasPrefix(route.Path, staticPath) && route.Method == ctx.Method() {
|
|
paramParts := parts[1:]
|
|
for _, paramValue := range paramParts {
|
|
for _, p := range route.Tmpl().Params {
|
|
ctx.Params().Set(p.Name, paramValue)
|
|
}
|
|
}
|
|
|
|
ctx.SetCurrentRoute(route.ReadOnly)
|
|
ctx.Do(route.Handlers)
|
|
return
|
|
}
|
|
}
|
|
|
|
// if nothing found...
|
|
ctx.StatusCode(iris.StatusNotFound)
|
|
}
|
|
|
|
func (r *customRouter) Build(provider router.RoutesProvider) error {
|
|
for _, route := range provider.GetRoutes() {
|
|
// do any necessary validation or conversations based on your custom logic here
|
|
// but always run the "BuildHandlers" for each registered route.
|
|
route.BuildHandlers()
|
|
// [...] r.routes = append(r.routes, *route)
|
|
}
|
|
|
|
r.provider = provider
|
|
return nil
|
|
}
|
|
|
|
func (r *customRouter) RouteExists(ctx iris.Context, method, path string) bool {
|
|
// [...]
|
|
return false
|
|
}
|
|
|
|
func (r *customRouter) FireErrorCode(ctx iris.Context) {
|
|
// responseStatusCode := ctx.GetStatusCode() // set by prior ctx.StatusCode calls
|
|
// [...]
|
|
}
|
|
|
|
func main() {
|
|
app := iris.New()
|
|
|
|
// In case you are wondering, the parameter types and macros like "{param:string $func()}" still work inside
|
|
// your custom router if you fetch by the Route's Handler
|
|
// because they are middlewares under the hood, so you don't have to implement the logic of handling them manually,
|
|
// though you have to match what requested path is what route and fill the ctx.Params(), this is the work of your custom router.
|
|
app.Get("/hello/{name}", func(ctx iris.Context) {
|
|
name := ctx.Params().Get("name")
|
|
ctx.Writef("Hello %s\n", name)
|
|
})
|
|
|
|
app.Get("/cs/{num:uint64 min(10) else 400}", func(ctx iris.Context) {
|
|
num := ctx.Params().GetUint64Default("num", 0)
|
|
ctx.Writef("num is: %d\n", num)
|
|
})
|
|
|
|
// To replace the existing router with a customized one by using the iris/context.Context
|
|
// you have to use the `app.BuildRouter` method before `app.Run` and after the routes registered.
|
|
// You should pass your custom router's instance as the second input arg, which must completes the `router#RequestHandler`
|
|
// interface as shown above.
|
|
//
|
|
// To see how you can build something even more low-level without direct iris' context support (you can do that manually as well)
|
|
// navigate to the "custom-wrapper" example instead.
|
|
myCustomRouter := new(customRouter)
|
|
app.BuildRouter(app.ContextPool, myCustomRouter, app.APIBuilder, true)
|
|
|
|
app.Listen(":8080")
|
|
}
|