diff --git a/_examples/README.md b/_examples/README.md
index 3f689aef..2592cd24 100644
--- a/_examples/README.md
+++ b/_examples/README.md
@@ -59,6 +59,7 @@
* [From func(http.HandlerFunc) http.HandlerFunc](convert-handlers/real-usecase-raven/writing-middleware/main.go)
* [Rewrite Middleware](routing/rewrite/main.go)
* [Route State](routing/route-state/main.go)
+ * [Remove Route](routing/remove-route/main.go)
* [Reverse Routing](routing/reverse/main.go)
* [Router Wrapper](routing/custom-wrapper/main.go)
* [Custom Router](routing/custom-router/main.go)
diff --git a/_examples/mvc/hello-world/main.go b/_examples/mvc/hello-world/main.go
index 4b3ce6bd..0cd9b8d6 100644
--- a/_examples/mvc/hello-world/main.go
+++ b/_examples/mvc/hello-world/main.go
@@ -1,11 +1,12 @@
package main
import (
+ "strings"
+
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/logger"
"github.com/kataras/iris/v12/middleware/recover"
"github.com/kataras/iris/v12/mvc"
- "strings"
)
// This example is equivalent to the
@@ -47,7 +48,7 @@ func newApp() *iris.Application {
w = strings.ToLower(w)
}
path += w
- return path
+ return path
}).Handle(new(ExampleControllerCustomPath))
return app
@@ -131,7 +132,6 @@ func (c *ExampleControllerCustomPath) GetHelloWorld() interface{} {
return map[string]string{"message": "Hello Iris! CustomPath"}
}
-
// GetUserBy serves
// Method: GET
// Resource: http://localhost:8080/user/{username:string}
diff --git a/_examples/routing/remove-route/main.go b/_examples/routing/remove-route/main.go
new file mode 100644
index 00000000..8c684ca1
--- /dev/null
+++ b/_examples/routing/remove-route/main.go
@@ -0,0 +1,24 @@
+package main
+
+import (
+ "github.com/kataras/iris/v12"
+)
+
+func main() {
+ app := iris.New()
+ app.Get("/", index)
+ app.Get("/about", about).SetName("about_page")
+ app.RemoveRoute("about_page")
+
+ // http://localhost:8080
+ // http://localhost:8080/about (Not Found)
+ app.Listen(":8080")
+}
+
+func index(ctx iris.Context) {
+ ctx.WriteString("Hello, Gophers!")
+}
+
+func about(ctx iris.Context) {
+ ctx.HTML("
About Page
")
+}
diff --git a/core/router/api_builder.go b/core/router/api_builder.go
index d1f32dd6..7f23294e 100644
--- a/core/router/api_builder.go
+++ b/core/router/api_builder.go
@@ -43,7 +43,7 @@ var AllMethods = []string{
// all the routes.
type repository struct {
routes []*Route
- pos map[string]int
+ paths map[string]*Route // only the fullname path part, required at CreateRoutes for registering index page.
}
func (repo *repository) get(routeName string) *Route {
@@ -70,12 +70,8 @@ func (repo *repository) getRelative(r *Route) *Route {
}
func (repo *repository) getByPath(tmplPath string) *Route {
- if repo.pos != nil {
- if idx, ok := repo.pos[tmplPath]; ok {
- if len(repo.routes) > idx {
- return repo.routes[idx]
- }
- }
+ if r, ok := repo.paths[tmplPath]; ok {
+ return r
}
return nil
@@ -85,6 +81,25 @@ func (repo *repository) getAll() []*Route {
return repo.routes
}
+func (repo *repository) remove(routeName string) bool {
+ for i, r := range repo.routes {
+ if r.Name == routeName {
+ lastIdx := len(repo.routes) - 1
+ if lastIdx == i {
+ repo.routes = repo.routes[0:lastIdx]
+ } else {
+ cp := make([]*Route, 0, lastIdx)
+ cp = append(cp, repo.routes[:i]...)
+ repo.routes = append(cp, repo.routes[i+1:]...)
+ }
+
+ delete(repo.paths, r.tmpl.Src)
+ return true
+ }
+ }
+ return false
+}
+
func (repo *repository) register(route *Route, rule RouteRegisterRule) (*Route, error) {
for i, r := range repo.routes {
// 14 August 2019 allow register same path pattern with different macro functions,
@@ -110,10 +125,10 @@ func (repo *repository) register(route *Route, rule RouteRegisterRule) (*Route,
repo.routes = append(repo.routes, route)
if route.StatusCode == 0 { // a common resource route, not a status code error handler.
- if repo.pos == nil {
- repo.pos = make(map[string]int)
+ if repo.paths == nil {
+ repo.paths = make(map[string]*Route)
}
- repo.pos[route.tmpl.Src] = len(repo.routes) - 1
+ repo.paths[route.tmpl.Src] = route
}
return route, nil
@@ -641,6 +656,17 @@ func (api *APIBuilder) CreateRoutes(methods []string, relativePath string, handl
return api.createRoutes(0, methods, relativePath, handlers...)
}
+// RemoveRoute deletes a registered route by its name before `Application.Listen`.
+// The default naming for newly created routes is: method + subdomain + path.
+// Reports whether a route with that name was found and removed successfully.
+//
+// Note that this method applies to all Parties (sub routers)
+// even if each of the Parties have access to this method,
+// as the route name is unique per Iris Application.
+func (api *APIBuilder) RemoveRoute(routeName string) bool {
+ return api.routes.remove(routeName)
+}
+
func (api *APIBuilder) createRoutes(errorCode int, methods []string, relativePath string, handlers ...context.Handler) []*Route {
if statusCodeSuccessful(errorCode) {
errorCode = 0
@@ -808,7 +834,7 @@ func (api *APIBuilder) Party(relativePath string, handlers ...context.Handler) P
copy(allowMethods, api.allowMethods)
// make a copy of the parent properties.
- var properties context.Map
+ properties := make(context.Map, len(api.properties))
for k, v := range api.properties {
properties[k] = v
}
@@ -924,11 +950,6 @@ func (api *APIBuilder) PartyConfigure(relativePath string, partyReg ...PartyConf
return child
}
-func (api *APIBuilder) configureParty(partyReg ...PartyConfigurator) Party {
-
- return api
-}
-
// Subdomain returns a new party which is responsible to register routes to
// this specific "subdomain".
//
diff --git a/core/router/party.go b/core/router/party.go
index d3d5ebf5..f4c487f5 100644
--- a/core/router/party.go
+++ b/core/router/party.go
@@ -388,6 +388,15 @@ type Party interface {
// This method can be used for third-parties Iris helpers packages and tools
// that want a more detailed view of Party-based Routes before take the decision to register them.
CreateRoutes(methods []string, relativePath string, handlers ...context.Handler) []*Route
+ // RemoveRoute deletes a registered route by its name before `Application.Listen`.
+ // The default naming for newly created routes is: method + subdomain + path.
+ // Reports whether a route with that name was found and removed successfully.
+ //
+ // Note that this method applies to all Parties (sub routers)
+ // even if each of the Parties have access to this method,
+ // as the route name is unique per Iris Application.
+ RemoveRoute(routeName string) bool
+
// StaticContent registers a GET and HEAD method routes to the requestPath
// that are ready to serve raw static bytes, memory cached.
//
diff --git a/core/router/route.go b/core/router/route.go
index c78ba3ce..f35e2a98 100644
--- a/core/router/route.go
+++ b/core/router/route.go
@@ -294,6 +294,16 @@ func (r *Route) DeepEqual(other *Route) bool {
return r.Equal(other) && r.tmpl.Src == other.tmpl.Src
}
+// SetName overrides the default route name which defaults to
+// method + subdomain + path and
+// statusErrorCode_method+subdomain+path for error routes.
+//
+// Note that the route name MUST BE unique per Iris Application.
+func (r *Route) SetName(newRouteName string) *Route {
+ r.Name = newRouteName
+ return r
+}
+
// ExcludeSitemap excludes this route page from sitemap generator.
// It sets the NoSitemap field to true.
//