New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[plugins] Introduce strict setup with abstract classes #2006
Conversation
ccec4d1
to
75e95b6
Compare
|
||
fun <CFG : PluginConfiguration> Consumer<CFG>.createUserConfig(cfg: CFG): CFG = | ||
cfg.also { accept(it) } | ||
abstract class NoConfigPlugin : JavalinPlugin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the fact that JavalinPlugin
interface is implemented by some abstract Plugin
and abstract NoConfigPlugin
.
- If we want to have both interface & abstract class, it should be called like
AbstractJavalinPlugin
/StandardJavalinPlugin
/etc. - The fact that there's
JavalinPlugin
interface already removes the need to follow our requirements defined by the abstract constructor (and that was one of the main reasons to start this change 🤔) - Instead of making a 3rd structure that represents a no-config plugin, you could just make the config parameters optional, so
Plugin<Void>
already tells us that there's no cfg.
I'd personally just stay with one abstract JavalinPlugin
class, instead of making variants of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Why should it be called that?
- In this PR,
registerPlugin
accepts either aPlugin
or aNoConfigPlugin
, theJavalinPlugin
interface is just used internally. TheregisterPlugin
function does not acceptJavalinPlugin
. - That's how I had it, but it becomes very hacky. You need to cast a null to be a non-null (or have a nullable config), and you get a class that has a
pluginConfig
property that sometimes doesn't actually exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One downside here is that people could potentially create their own NoConfigPlugin with a custom configuration 😓
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the hack is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added an exception to make it less hacky.
Just to say that from the perspective of avaje-http code generation for Javalin, the To me, it almost looks like there are 2 concepts in play there now with the generic type / consuming the generic type. For the avaje-http use, it is generating a "Route" and with Javalin 6 beta this is something that now |
Indeed, it is specific to what avaje-http seems to be doing. Javalin's API is focused on our end-users (so probably like 99%+ of people that don't write plugins, but use these already available in the ecosystem). Before 6.x, each plugin was kinda a new independent world, because plugin authors defined the API & init phase the way they wanted, not the way that matched some kind of official guideline. That's something we've decided to address, so since 6.x, users should expect the same approach across different plugins: Javalin.createAndStart { cfg ->
cfg.registerPlugin(SslPlugin {
it.abc = true
})
cfg.registerPlugin(OpenApiPlugin {
it.def = false
})
cfg.registerPlugin(AbcPlugin()) // plugin without config (repredented by Plugin<Void>)
} Plugins are represented by the abstract class that requires a supplier & default cfg in the constructor, so it creates a natural requirement from authors to follow that pattern. Despite the fact, that having something like class AvajeHttpRouting : RoutingApiInitializer<Void> {
override fun initialize(cfg: JavalinConfig, internalRouter: InternalRouter, setup: Consumer<Void>) {
// register your routes directly in `internalRouter` or via cfg
}
}
Javalin.createAndStart { cfg ->
cfg.router.mount(AvajeHttpRouting())
} |
@dzikoysk gave a very nice summary. Our main focus is on plugin consumers (hehe), not plugin authors. That being said, we do of course want to make things as nice as possible for plugin authors too. |
No description provided.