Skip to content

Ability to create endpoints/routes dynamically (IE and endpoint creating another endpoint at runtime)? #371

Open
@GavinRay97

Description

@GavinRay97

Hello, this is quite a fantastic library you've made available!

The only thing I haven't been able to figure out from the examples available + source code is whether it's possible to programmatically/dynamically create new routes?

To test this, I tried to have an endpoint /sample create a route /new, but what gets returned is just the empty "whitelabel" page.

This is with Spring Boot 2.6-SNAPSHOT and the 0.4.5-SNAPSHOT of Spring-Fu:

package org.hasura.polyglot

import scala.beans.BeanProperty
import reactor.core.publisher.Mono
import org.springframework.fu.jafu.Jafu.reactiveWebApplication
import org.springframework.fu.jafu.webflux.WebFluxServerDsl
import org.springframework.fu.jafu.webflux.WebFluxServerDsl.webFlux
import org.springframework.web.reactive.function.server.ServerRequest
import org.springframework.web.reactive.function.server.ServerResponse
import org.springframework.web.reactive.function.server.ServerResponse.ok
import org.springframework.web.reactive.function.server.RouterFunctions

case class Sample(@BeanProperty message: String)

class SampleService:
  def generateMessage(): String = "Hello world!"

class SampleHandler(private var sampleService: SampleService):
  def hello(request: ServerRequest): Mono[ServerResponse] =
    ServerResponse.ok().bodyValue(sampleService.generateMessage())

  def json(request: ServerRequest): Mono[ServerResponse] =
    ServerResponse.ok().bodyValue(new Sample(sampleService.generateMessage()))

def mkRoutes(server: WebFluxServerDsl)(app: RouterFunctions.Builder) =
  val handler = server.ref(classOf[SampleHandler])

  app.GET("/sample", req => {
    println("Called /sample handler, attempting to dynamically create endpoint...")
    app.GET("/new", req => {
      println("/new endpoint created from within /sample")
      ServerResponse.ok().bodyValue("dynamically created during GET /sample request")
    })
    ServerResponse.ok().bodyValue("hello")
  })

  app.GET("/", req => {
    handler.hello(req)
  })

  app.GET("/api", handler.json)

object Application:
  val app = reactiveWebApplication(a => {
    a.beans(b => {
      b.bean(classOf[SampleHandler])
      b.bean(classOf[SampleService])
    })

    a.enable(
        webFlux(server =>
          server
            .port(if server.profiles().contains("test") then 8181 else 8080)
            .router(mkRoutes(server))
            .codecs(_.string().jackson())
        )
    )
  })

  def main(args: Array[String]): Unit = app.run(args)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions