examples: writing an API for the Apache Kafka: add a root handler for routes documentation to make navigation easier and add some other methods that may find them useful for request state and routes description

Former-commit-id: 3775aab2386051b23e127ccc9e3a6accdfdee6d0
This commit is contained in:
Gerasimos (Makis) Maropoulos 2018-08-05 13:51:05 +03:00
parent 2b2492abfa
commit e5f6bce86f
8 changed files with 97 additions and 2 deletions

View File

@ -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()
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -9,6 +9,8 @@ Read [the fully functional example](src/main.go).
## Screens
![](0_docs.png)
![](1_create_topic.png)
![](2_list_topics.png)

View File

@ -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(`<!DOCTYPE html>
<html>
<head>
<style>
th, td {
border: 1px solid black;
padding: 15px;
text-align: left;
}
</style>
</head>`)
defer ctx.Writef("</html>")
ctx.Writef("<body>")
defer ctx.Writef("</body>")
ctx.Writef(`
<table>
<tr>
<th>Method</th>
<th>Path</th>
<th>Handler</th>
</tr>
`)
defer ctx.Writef(`</table>`)
registeredRoutes := ctx.Application().GetRoutesReadOnly()
for _, r := range registeredRoutes {
if r.Path() == "/" { // don't list the root, current one.
continue
}
ctx.Writef(`
<tr>
<td>%s</td>
<td>%s%s</td>
<td>%s</td>
</tr>
`, r.Method(), ctx.Host(), r.Path(), r.MainHandlerName())
}
}
type httpError struct {
Code int `json:"code"`
Reason string `json:"reason"`

View File

@ -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.
//

View File

@ -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
}

View File

@ -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.
//

View File

@ -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
}