Skip to content

Tighter integration between BeanRegistrarDsl and RouterFunctionDsl #35549

@wakingrufus

Description

@wakingrufus

When declaring RouterFunctions with RouterFunctionDsl, in order to inject required beans, we are forced to use the slightly verbose beanProvider from the outer scope of the SupplierContextDsl. This means that code which defines the routes is also implicitly coupled to usage within that context. For example:

BeanRegistrarDsl({
	registerBean<InjectedBean>()
	registerBean {
		router {
			GET("/baz") {
				ok().header("hello", beanProvider<InjectedBean>().getObject().sayHi()).build()
			}
		}
	}
}

This presents a problem when we attempt to decompose our DSL usage.
For example, this does not work

val myRoutes  = { bean : InjectedBean  -> {
		router {
			GET("/baz") { ok().header("hello", bean.sayHi()).build() }
		}
	}
}
BeanRegistrarDsl({
	registerBean<InjectedBean>()
	registerBean(::routes)
}

In order to make it work, the router DSL must be extracted as

val routes: (BeanRegistrarDsl.SupplierContextDsl<RouterFunction<ServerResponse>>) -> RouterFunction<ServerResponse> = { context ->
		router {
			GET("/baz") { ok().header("hello", context.beanProvider<InjectedBean>().getObject().sayHi()).build() }
		}
	}

Which is verbose and clunky.
With some extension functions, we can create the experience for injection to be like this:

BeanRegistrarDsl({
	registerBean<InjectedBean>()
	registerBean {
		routes { bean: InjectedBean ->
			{
				GET("/baz") { ok().header("hello", bean.sayHi()).build() }
			}
		}
	}
})

or, with decomposition:

val myRoutes = router { bean: InjectedBean ->
	{
		GET("/baz") { ok().header("hello", bean.sayHi()).build() }
	}
}
BeanRegistrarDsl({
	registerBean<InjectedBean>()
	registerBean {
		myRoutes()
	}
})

I will open a draft PR to show how this could be implemented

Metadata

Metadata

Assignees

Labels

status: waiting-for-triageAn issue we've not yet triaged or decided ontheme: kotlinAn issue related to Kotlin support

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions