spring-fu icon indicating copy to clipboard operation
spring-fu copied to clipboard

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

Open GavinRay97 opened this issue 3 years ago • 0 comments

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)

GavinRay97 avatar Jun 27 '21 23:06 GavinRay97