-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Allow Build time OpenAPI Filters #36152
Allow Build time OpenAPI Filters #36152
Conversation
...nsions/smallrye-openapi/runtime/src/main/java/io/quarkus/smallrye/openapi/OpenApiFilter.java
Outdated
Show resolved
Hide resolved
Interesting. What happens if there are only |
...penapi/runtime/src/main/java/io/quarkus/smallrye/openapi/runtime/OpenApiDocumentService.java
Outdated
Show resolved
Hide resolved
Shouldn't be, I can double check, maybe need to check for empty list before calling the recorder |
I'll address all issues when I do the final PR, with the release SmallRye lib. Thanks @geoand |
a8e2f7a
to
ccbac8a
Compare
This comment has been minimized.
This comment has been minimized.
ccbac8a
to
f125426
Compare
Signed-off-by: Phillip Kruger <[email protected]>
f125426
to
0c06947
Compare
This comment has been minimized.
This comment has been minimized.
✔️ The latest workflow run for the pull request has completed successfully. It should be safe to merge provided you have a look at the other checks in the summary. |
@phillip-kruger But there is one question left: |
This sounds like a bug. Do you have a reproducer? |
For now i have the effect in my production code only. I will try to reproduce in in small sample project if i find some time for that... |
@phillip-kruger i created a minimal quarkus project with an OASFilter at stage BUILD: @OpenApiFilter(OpenApiFilter.RunStage.BUILD)
public class MyApiFilter implements OASFilter {
IndexView jandex;
private static final AtomicInteger RUN = new AtomicInteger();
public MyApiFilter(IndexView aIndex) {
jandex = aIndex;
}
@Override
public void filterOpenAPI(OpenAPI aOpenAPI) {
Logger.getLogger("MyApiFilter").info("OpenApiFilter.filterOpenAPI() Attempt no " + RUN.incrementAndGet());
aOpenAPI.info(OASFactory.createInfo().description("MyApiFilter was visited " + RUN.get() + " times"));
}
} It seems the Filter is triggered twice:
See also the generated OpenApi.yaml under ---
openapi: 3.0.3
info:
title: Generated API
description: MyApiFilter was visited 2 times
version: 1.0.0-SNAPSHOT
servers:
- url: http://localhost:8080
description: Auto generated value
- url: http://0.0.0.0:8080
description: Auto generated value
paths:
/hello:
get:
tags:
- Greeting Resource
summary: Hello API
responses:
"200":
description: OK
content:
text/plain:
schema:
type: string |
@ChMThiel - Yes you will see that it runs twice. So the first time is when we create a static document, that gets included in the runtime artifact. The static document will again be loaded in runtime by OpenAPI and all runtime filters will also run, and a final document will be created, and that is the one you see in runtime (http://localhost:8080/q/openapi?format=json). In you example you will see that this document description is "MyApiFilter was visited 1 times". The second one is where we, in build time, try and create a similar document, so we run the runtime filters on build time, as some might work. In fact, before this change when all users filters was runtime, this was to included those (if possible). This document can then be stored (like what you do with the config option) but even if you do not store it, it gets passed along the build chain for other extensions to pick up. Example, extensions that creates code from this document. I hope this explains it ? If not please let me know. Unfortunately we can not reuse the same document as the one (maybe) has runtime filters added where the other has not. We can maybe check if there are any runtime filters, and if not, we don't do this ? Can you provide more context on why this (running twice) a problem for you ? |
@phillip-kruger Thanks for the quick response. I think i do understand now, why the filters are visited more than once. The Problem i have is that the stored openapi.yaml during build differs (slightly) from the one you get from the runtime-download if i don't do all my filter-stuff idempotently (which i didn't up to now). @GET
@Produces(MediaType.TEXT_PLAIN)
@Operation(summary = "Hello API", description = "hello description from schema")
public String hello() {
return "Hello RESTEasy";
} and my filter: @Override
public Operation filterOperation(Operation aOperation) {
return aOperation.description(aOperation.getDescription() + " my added description");
} my openapi.yaml.file stored in /target/generated-resources/openapi will contain (In my real project i search for custom beanvalidations and add the findings as description-texts) We use the build-time openapi.yaml in our pipeline to build a client-library, store it versionized in a repo to have an audit-trail of the API-changes, etc. So this might lead to problems if the file we use here differs from the one you see in swagger or get by download (...even if it's currently only differences in descriptions/summaries). |
Another point: What do you think: Should the filter support ordering? Something like |
Yeah, so that is not ideal, I think we can get a better way to do this so that your filter is not run twice. I can look at this. Basically we need to create a document (for inclusion in the runtime), and then use that and only add runtime filters when we store. I am about to take a break (summer holiday) so I'll only look at this next year. If you are in a hurry, you are welcome to do a PR ? W.r.t priority, yeah that is something we can add. Having multiple filters is Quarkus specific (the spec only allow one) so from a spec p.o.w a user needs to do everything in one filter. But because we allow many we can look at a way to order them for sure |
Thank you very much! It's not urgent...and i will be on holiday myself, too 🎄 |
@phillip-kruger As mentioned above, i use the jandex in an OpenApiFilter to recognize BeanValidations and document them. I finally finished my first POC for this (see OpenApiBeanValidationFilter). Maybe you want to have a look. I just published a complete Quarkus-demo-application, but basically all you need is the |
This PR allows users to define Multiple Filters, and allow users to define the filters to run in build time. Users can use an annotation to do this:
Draft for now, waiting for SmallRye release.
/cc @MikeEdgar
/cc @ChMThiel
see this discussion: smallrye/smallrye-open-api#1475