quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.35k stars 2.56k forks source link

Add ability to hide rest endpoints from OpenAPI schema / Swagger #40007

Open rsvoboda opened 2 months ago

rsvoboda commented 2 months ago

Description

I'm unable to hide JAXRS methods in OpenAPI schema / Swagger.

For endpoints that are experimental or legacy ones I don't want them to be part of the generated schema. That schema serves as public contract in many cases.

I found io.swagger.v3.oas.annotations.Hidden annotation, but no equivalent of it in Quarkus OpenAPI extension. SB has ways to hide endpoints from the generated document even without using @Hidden annotation.

Please add ability to hide rest endpoints from OpenAPI schema / Swagger.

Implementation ideas

No response

quarkus-bot[bot] commented 2 months ago

/cc @EricWittmann (openapi), @MikeEdgar (openapi,swagger-ui), @phillip-kruger (openapi,swagger-ui)

phillip-kruger commented 2 months ago

We do not support the swagger annotations. Please use MicroProfile OpenAPI

phillip-kruger commented 2 months ago

Example: if this is an operation you can do @Operation(hidden=true) (use package org.eclipse.microprofile.openapi.annotations)

rsvoboda commented 2 months ago

Thanks @phillip-kruger, this helps a lot!

As stated in description of this issue, I was able to find a lot of resources describing swagger way and even more resources for SB. I looked into openapi for examples, I scraped https://github.com/eclipse/microprofile-open-api/blob/main/spec/src/main/asciidoc/microprofile-openapi-spec.asciidoc too, but nothing popped up.

https://quarkus.io/guides/openapi-swaggerui guide could be extended with examples how to hide methods/endpoints and fields of returrned objects. Seems that we are expecting that people are quite familiar with Eclipse MicroProfile OpenAPI and all the constructs it allows, but in reality there are not many resources that people can use.

phillip-kruger commented 2 months ago

Agree, we can definitely update the docs. We also have on our to-do list to add support for swagger annotations, but it has never really been a priority. See https://github.com/smallrye/smallrye-open-api/issues/752

Serkan80 commented 2 months ago

@rsvoboda this is already possible, but it is nowhere documented and I found it by accident.

So it works something like this:

import io.quarkus.runtime.StartupEvent;
import io.quarkus.runtime.rest.DisabledRestEndpoints;
import jakarta.enterprise.event.Observes;
import org.eclipse.microprofile.config.inject.ConfigProperty;

import java.util.HashMap;
import java.util.List;

/**
 * Removes the internal api's from the Swagger UI & OpenAPI yaml.
 */
public class SwaggerUiConfig {

    @ConfigProperty(name = "swagger-ui.show-internal-apis")
    boolean showInternalApis;

    @ConfigProperty(name = "swagger-ui.disabled-paths")
    List<String> disabledPaths;

    public void init(@Observes StartupEvent event) {
        if (!this.showInternalApis) {
            var result = new HashMap<String, List<String>>();
            this.disabledPaths.forEach(path -> result.put(path, List.of("DELETE", "POST", "PATCH", "PUT")));
           DisabledRestEndpoints.set(result);
       }
   }
}

application.properties:

mp.openapi.filter=io.quarkus.smallrye.openapi.runtime.filter.DisabledRestEndpointsFilter

swagger-ui.show-internal-apis=false
%dev.swagger-ui.show-internal-apis=true
swagger-ui.disabled-paths=/v1/admin/fruits,/v1/management/fruits/

Note that the disabled-path names should match the path names in your openapi.yml.

I hope this helps you.

rsvoboda commented 2 months ago

Thanks @Serkan80! It's good there a way to achieve this right now. Quarkus should provide simpler way through annotation.

Serkan80 commented 2 months ago

@rsvoboda I'm afraid that to achieve this through annotation, is going to be hard, because this needs to be a part of the MP OpenApi specification. So everyone needs to agree on it, and this can take a while. For the time being, this solution is good enough for me.

MikeEdgar commented 2 months ago

Have you looked at using mp.openapi.scan.exclude.classes or mp.openapi.scan.exclude.packages to skip the resources implementing the endpoints you'd like to hide?