Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to hide endpoints from Swagger documentation with Springfox

I have a Spring Boot project with next dependency of Springfox:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
    <scope>compile</scope>
</dependency>

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

And I have my Interface:

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

@RestController
@RequestMapping(value = "/cache")
@ApiIgnore
@Api(hidden = true)
public interface CacheController {

    @RequestMapping(
        value = "clear/",
        method = RequestMethod.GET,
        produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE}
    )
    @ApiOperation(value = "", hidden = true)
    ResponseEntity<String> clearToken();
}

The annotations @ApiIgnore and @Api(hidden = true) (I've tested them separately and they don't work either.) haven't effects to hide the documentation. It only works if the annotation is over the method, but I would like hide them all since I have other endpoints I'd like to hide.

Some ideas?

EDIT:

This is my Swagger configuration:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseMessageBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.ResponseMessage;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    public static String API_KEY_NAME;

    @Bean
    public Docket apiDocumentation() {
        List<ResponseMessage> errorList = this.defineResponseMessages();

        return new Docket(DocumentationType.SWAGGER_2)  
          .select()       
          .apis(RequestHandlerSelectors.basePackage("my.package.rest"))              
          .paths(PathSelectors.any())                          
          .build()
          .useDefaultResponseMessages(true)
          .globalResponseMessage(RequestMethod.GET, errorList)
          .securitySchemes(Arrays.asList(this.apiKey()))
          .securityContexts(Arrays.asList(this.securityContext()))
          .apiInfo(this.apiInfo());                                          
    }

    @Value("${server.security.apiKeyName}")
    public void setApiKeyName(final String apiKeyName) {
        SwaggerConfig.API_KEY_NAME = apiKeyName;
    }

    private ApiKey apiKey() {
        return new ApiKey("apiKey", API_KEY_NAME, "header");
    }

    private SecurityContext securityContext() {
        return SecurityContext.builder()
            .securityReferences(defaultAuth())
            .forPaths(PathSelectors.any()).build();
    }

    private List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return Arrays.asList(new SecurityReference("apiKey", authorizationScopes));
    }

    private List<ResponseMessage> defineResponseMessages() {
        List<ResponseMessage> errorList = new ArrayList<ResponseMessage>();

        ResponseMessage responseMessage = new ResponseMessageBuilder()
            .code(HttpStatus.INTERNAL_SERVER_ERROR.value())
            .message(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase())
            .build();

        errorList.add(responseMessage);

        responseMessage = new ResponseMessageBuilder()
                .code(HttpStatus.UNAUTHORIZED.value())
                .message(HttpStatus.UNAUTHORIZED.getReasonPhrase())
                .build();

        errorList.add(responseMessage);

        responseMessage = new ResponseMessageBuilder()
                .code(HttpStatus.NOT_FOUND.value())
                .message(HttpStatus.NOT_FOUND.getReasonPhrase())
                .build();

        errorList.add(responseMessage);

        return errorList;
    }

    private ApiInfo apiInfo() {
        ApiInfoBuilder apiInfoBuilder = new ApiInfoBuilder();
        return apiInfoBuilder
            .title("My API")
            .description("Description")
            .version("1.0.0 Beta")
            .build();
    }
}
like image 952
Alberto Avatar asked Mar 05 '19 19:03

Alberto


People also ask

How do I hide fields in Swagger?

We can use the hidden property of the annotation to hide a field in the definition of a model object in Swagger UI. Let's try it for the id field: @ApiModelProperty(hidden = true) private int id; In the above scenarios, we find that the id field is hidden for both GET and POST APIs.

How do I hide a method in Swagger?

Another simple approach is to use the ApiExplorerSettings attribute on all the methods for which documentation needs not to be created. You can apply ApiExplorerSettings on the Controller also to be able to ignore all methods under that Controller.

How do I hide models in Swagger UI?

To hide the "Models" section, add defaultModelsExpandDepth: -1 to the Swagger UI configuration code in your index. html . Note the option name uses plural Model*s* not Model . Swagger UI also has many other configuration options that control API documentation rendering.


5 Answers

You have added the @ApiIgnore annotation on an interface. It looks like, this annotation doesn't work when added on an interface. (I really don't understand why @Api works on an interface and @ApiIgnore don't. 😕)

Add the annotation directly to your controller class. This should solve your problem.

The hidden property on the @Api annotation doesn't work currently. (See this GitHub issue.)

like image 108
Matt Ke Avatar answered Oct 24 '22 06:10

Matt Ke


For OpenAPI3 and SpringBoot:
I used @Hidden annotation on a method of a controller.
It seems to work both at method level and controller level.

@Hidden annotation was imported from using:

import io.swagger.v3.oas.annotations;
like image 38
u33how Avatar answered Oct 24 '22 08:10

u33how


One more way is to use @ApiOperation(hidden = true) This can be used at controller/handler level method. E.g.

@RestController
public HomeController{
@ApiOperation(value = "<Your Message>", hidden = true)
    public String getMessage(@RequestParam(value = "msg") final String msg){
        return msg;
    }
}
like image 21
Purushotham CK Avatar answered Oct 24 '22 06:10

Purushotham CK


The scenario where we want to hide only a particular method(s) from the class. For swagger.v3 there is an annotation with name Hidden in io.swagger.core.v3:swagger-annotations:2.0.10 jar. Methods to be hidden can be annotated with Hidden annotation as shown below. The below method shows the method with DELETE operation which needs to be hidden from the swagger documentation.

@DELETE
@Hidden
public void deleteList(int id) {
//code goes here.
}
like image 4
user2122524 Avatar answered Oct 24 '22 06:10

user2122524


Another different great way is to define the visible paths on the SpringFox Configuration

@Configuration
@EnableSwagger2
public class SpringFoxConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(Predicates.or(PathSelectors.ant("/rtm/**"), PathSelectors.ant("/appview/**")))
                .build().apiInfo(apiEndPointsInfo());
    }
}

This way you can define the visible paths centraly and avoid puting swagger annotations on many controllers.

like image 1
Helias Karagozidis Avatar answered Oct 24 '22 07:10

Helias Karagozidis