-
Notifications
You must be signed in to change notification settings - Fork 12
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
Improve developer experience and documentation of registering custom ProblemPostProcessor
#312
Changes from all commits
d3310b6
8166011
2176568
c5ae38c
57c96c2
f805370
d1386b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.tietoevry.quarkus.resteasy.problem; | ||
|
||
import com.tietoevry.quarkus.resteasy.problem.postprocessing.ProblemContext; | ||
import com.tietoevry.quarkus.resteasy.problem.postprocessing.ProblemPostProcessor; | ||
import io.quarkus.runtime.Startup; | ||
import jakarta.enterprise.context.ApplicationScoped; | ||
import jakarta.inject.Inject; | ||
import jakarta.validation.Validator; | ||
|
||
@ApplicationScoped | ||
@Startup | ||
class CustomPostProcessor implements ProblemPostProcessor { | ||
|
||
@Inject | ||
Validator validator; | ||
|
||
@Override | ||
public HttpProblem apply(HttpProblem problem, ProblemContext context) { | ||
return HttpProblem.builder(problem) | ||
.with("injected_from_custom_post_processor", "you called " + context.path) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
|
||
import com.tietoevry.quarkus.resteasy.problem.ExceptionMapperBase; | ||
import io.quarkus.runtime.annotations.Recorder; | ||
import jakarta.enterprise.inject.spi.CDI; | ||
import java.util.Set; | ||
|
||
/** | ||
|
@@ -24,4 +25,9 @@ public void enableMetrics() { | |
ExceptionMapperBase.postProcessorsRegistry.register(new MicroprofileMetricsCollector()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since a user should not call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not that you should not call it - it's not forbidden, but you're right - it could have been package private. As such change is breaking, we can do it in 4.0 earliest though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah ok, I thought your intention was not to offer this API publicly. But yeah, fine to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't really matter now what my intention was, it would be api breaking change, and - if we want to be predictable and compliant with semver - we can't change it |
||
} | ||
|
||
public void registerCustomPostProcessors() { | ||
CDI.current().select(ProblemPostProcessor.class) | ||
pazkooda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.forEach(ExceptionMapperBase.postProcessorsRegistry::register); | ||
} | ||
|
||
} |
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 would a user instantiate such a bean eagerly? AFAIK you register the bean(s) via a static main method (STATIC_INIT) anyway. If your intention is to avoid that Quarkus removes the "unused" bean, I would recommend to use
@io.quarkus.arc.Unremovable
instead.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.
Registering CDI beans as postprocessors happens in runtime (RUNTIME_INIT):
If you reference your postprocessor from other beans then this annotation is not needed (Quarkus will create and register it as bean in CDI on startup), but if it's not (and I believe it to be true in most cases) this bean will never be created.
@Unremovable
- as far as I undestand - does not affect how the bean is instantiated (lazily or eagerly) - from this extension's point of view Quarkus can remove this bean immediately after startup. But the bean needs to be registered in CDI in RUNTIME_INIT phase for this autoregistration to work correctly.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.
Sure, my fault.
Marking a bean
@Unremovable
is mentioned in the offical guide especially for that case u have implemented:Please refer to Remove unused beans.
From my understanding, although the bean looks "unused", it won't get removed. Exactly what we want. Thus a proxy gets instantiated (since it is @ApplicationScoped see nonstandard features) and lazily created when registered at
RUNTIME_INIT
. Otherwise I cannot explain why this code works ..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.
You're right,
@Unremovable
will work as well (I falsely assume removability is about runtime, but in fact it's about build time), I will add this to the example as possible option to use instead of@Startup
.Nevertheless I don't think there's anything particularly wrong with
@Startup
, which makes the bean unremovable (by implicitly declaring an observer method)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.
Yeah, totally agree with that. I've just suggested another idea which could state the intention a little bit more explicitly.
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 one last idea. How about adding an additional build-step which marks each
@ProblemPostProcessor
as unremovable:By doing so, no additional annotation is required and the user doesn't need to be aware of any Quarkus internals.
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.
That looks neat indeed, a tiny bit of magic, but it looks like it's worth it. I'll look into it later.
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.
@chberger works like a charm, thanks
c69cc6a