vert-x3 / vertx-web

HTTP web applications for Vert.x
Apache License 2.0
1.11k stars 535 forks source link

Mount subRouters on patterns #2673

Open Brada-Groep opened 2 weeks ago

Brada-Groep commented 2 weeks ago

Mount subRouters on patterns

Allow the mounting of sub-routers on patterns and pass the data to the sub-routers mounted on them.

Use cases

There are many use cases, one of which is being able to organise your code more, but this one is the most important I think:

Scope

This way it would be able to put your entire application in a "scope".

example

I'm creating an application that has different spaces, every space has its own data, but is functionally the same. What I want to be able to do is the following:

val subRouter = Router.router(vertx)

subRouter.get("/get-all-data").handler { context ->
  var client = getConnection(vertx)
  val spaceDb = getDbForSpace(context.subRouterData?.get("space"))
  val testSql = "SELECT * FROM $spaceDb.products"
  client.preparedQuery(testSql).execute().onFailure { e ->
    val errorResultString = "an error occurred: ${e.message}"
    println(errorResultString)
    context.response().end(errorResultString)
  }.onSuccess { result: RowSet<Row> ->
    val testResult = "$testSql produces ${result.size()} rows!"
    println(testResult)
    context.response().end(testResult)
  }
}

mainRouter.route("/:space*").subRouter(addProductRouter) { ctx ->
  ctx.insertSubRouterData("space", ctx.pathParam("space"))
}

This would be implemented along the lines of:

// This is a Kotlin extension function, but in Java, this would be placed inside the Route class
fun Route.subRouter(subRouter: Router, handler: (RoutingContext) -> Unit) {
  this.handler { ctx ->
    // execute provided handler
    handler(ctx)
    // pass the request handling to the sub-router
    ctx.next()
  }
  this.subRouter(subRouter)
}

Contribution

I do not have the required knowledge to properly implement this feature. But I think this would be a welcome addition to the platform.