diff --git a/_examples/http_responsewriter/sse/main.go b/_examples/http_responsewriter/sse/main.go
index 5d0fe05d..b537524b 100644
--- a/_examples/http_responsewriter/sse/main.go
+++ b/_examples/http_responsewriter/sse/main.go
@@ -114,7 +114,7 @@ func (b *Broker) ServeHTTP(ctx context.Context) {
ctx.Writef("data: %s\n\n", <-messageChan)
// or json: data:{obj}.
- // Flush the data immediatly instead of buffering it for later.
+ // Flush the data immediately instead of buffering it for later.
flusher.Flush()
}
}
diff --git a/_examples/tutorial/api-for-apache-kafka/0_docs.png b/_examples/tutorial/api-for-apache-kafka/0_docs.png
new file mode 100644
index 00000000..2c81a744
Binary files /dev/null and b/_examples/tutorial/api-for-apache-kafka/0_docs.png differ
diff --git a/_examples/tutorial/api-for-apache-kafka/README.md b/_examples/tutorial/api-for-apache-kafka/README.md
index b478b229..bb53e1d0 100644
--- a/_examples/tutorial/api-for-apache-kafka/README.md
+++ b/_examples/tutorial/api-for-apache-kafka/README.md
@@ -9,6 +9,8 @@ Read [the fully functional example](src/main.go).
## Screens
+![](0_docs.png)
+
![](1_create_topic.png)
![](2_list_topics.png)
diff --git a/_examples/tutorial/api-for-apache-kafka/src/main.go b/_examples/tutorial/api-for-apache-kafka/src/main.go
index 4448a349..9b7b5d05 100644
--- a/_examples/tutorial/api-for-apache-kafka/src/main.go
+++ b/_examples/tutorial/api-for-apache-kafka/src/main.go
@@ -65,12 +65,60 @@ func main() {
}
}
+ app.Get("/", docsHandler)
+
+ // GET : http://localhost:8080
// POST, GET: http://localhost:8080/api/v1/topics
// POST : http://localhost:8080/apiv1/topics/{topic}/produce?key=my-key
// GET : http://localhost:8080/apiv1/topics/{topic}/consume?partition=0&offset=0 (these url query parameters are optional)
app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
}
+// simple use-case, you can use templates and views obviously, see the "_examples/views" examples.
+func docsHandler(ctx iris.Context) {
+ ctx.ContentType("text/html") // or ctx.HTML(fmt.Sprintf(...))
+ ctx.Writef(`
+
+
+
+ `)
+ defer ctx.Writef("")
+
+ ctx.Writef("")
+ defer ctx.Writef("")
+
+ ctx.Writef(`
+
+
+ Method |
+ Path |
+ Handler |
+
+ `)
+ defer ctx.Writef(`
`)
+
+ registeredRoutes := ctx.Application().GetRoutesReadOnly()
+ for _, r := range registeredRoutes {
+ if r.Path() == "/" { // don't list the root, current one.
+ continue
+ }
+
+ ctx.Writef(`
+
+ %s |
+ %s%s |
+ %s |
+
+ `, r.Method(), ctx.Host(), r.Path(), r.MainHandlerName())
+ }
+}
+
type httpError struct {
Code int `json:"code"`
Reason string `json:"reason"`
diff --git a/context/application.go b/context/application.go
index 9a94fbcb..36c973a0 100644
--- a/context/application.go
+++ b/context/application.go
@@ -42,6 +42,11 @@ type Application interface {
// Look core/router/APIBuilder#GetRoute for more.
GetRouteReadOnly(routeName string) RouteReadOnly
+ // GetRoutesReadOnly returns the registered "read-only" routes.
+ //
+ // Look core/router/APIBuilder#GetRoutes for more.
+ GetRoutesReadOnly() []RouteReadOnly
+
// FireErrorCode executes an error http status code handler
// based on the context's status code.
//
diff --git a/context/route.go b/context/route.go
index 52f29515..e632f11f 100644
--- a/context/route.go
+++ b/context/route.go
@@ -1,5 +1,7 @@
package context
+import "github.com/kataras/iris/core/router/macro"
+
// RouteReadOnly allows decoupled access to the current route
// inside the context.
type RouteReadOnly interface {
@@ -29,4 +31,15 @@ type RouteReadOnly interface {
// ResolvePath returns the formatted path's %v replaced with the args.
ResolvePath(args ...string) string
+
+ // Tmpl returns the path template,
+ // it contains the parsed template
+ // for the route's path.
+ // May contain zero named parameters.
+ //
+ // Available after the build state, i.e a request handler or Iris Configurator.
+ Tmpl() macro.Template
+
+ // MainHandlerName returns the first registered handler for the route.
+ MainHandlerName() string
}
diff --git a/core/router/api_builder.go b/core/router/api_builder.go
index 977f5d04..242fbadb 100644
--- a/core/router/api_builder.go
+++ b/core/router/api_builder.go
@@ -437,6 +437,7 @@ func (api *APIBuilder) GetRoute(routeName string) *Route {
// One note: "routeName" should be case-sensitive. Used by the context to get the current route.
// It returns an interface instead to reduce wrong usage and to keep the decoupled design between
// the context and the routes.
+// Look `GetRoutesReadOnly` to fetch a list of all registered routes.
//
// Look `GetRoute` for more.
func (api *APIBuilder) GetRouteReadOnly(routeName string) context.RouteReadOnly {
@@ -447,6 +448,24 @@ func (api *APIBuilder) GetRouteReadOnly(routeName string) context.RouteReadOnly
return routeReadOnlyWrapper{r}
}
+// GetRoutesReadOnly returns the registered routes with "read-only" access,
+// you cannot and you should not change any of these routes' properties on request state,
+// you can use the `GetRoutes()` for that instead.
+//
+// It returns interface-based slice instead of the real ones in order to apply
+// safe fetch between context(request-state) and the builded application.
+//
+// Look `GetRouteReadOnly` too.
+func (api *APIBuilder) GetRoutesReadOnly() []context.RouteReadOnly {
+ routes := api.GetRoutes()
+ readOnlyRoutes := make([]context.RouteReadOnly, len(routes))
+ for i, r := range routes {
+ readOnlyRoutes[i] = routeReadOnlyWrapper{r}
+ }
+
+ return readOnlyRoutes
+}
+
// Use appends Handler(s) to the current Party's routes and child routes.
// If the current Party is the root, then it registers the middleware to all child Parties' routes too.
//
diff --git a/core/router/route.go b/core/router/route.go
index 205687c1..346c068d 100644
--- a/core/router/route.go
+++ b/core/router/route.go
@@ -114,7 +114,7 @@ func (r Route) String() string {
r.Method, r.Subdomain, r.Tmpl().Src)
}
-// Tmpl returns the path template, i
+// Tmpl returns the path template,
// it contains the parsed template
// for the route's path.
// May contain zero named parameters.
@@ -249,3 +249,11 @@ func (rd routeReadOnlyWrapper) Path() string {
func (rd routeReadOnlyWrapper) Trace() string {
return rd.Route.Trace()
}
+
+func (rd routeReadOnlyWrapper) Tmpl() macro.Template {
+ return rd.Route.Tmpl()
+}
+
+func (rd routeReadOnlyWrapper) MainHandlerName() string {
+ return rd.Route.MainHandlerName
+}