How to hide endpoints from Swagger documentation with Springfox
Asked Answered
D

6

20

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();
    }
}
Drainpipe answered 5/3, 2019 at 19:42 Comment(2)
What does your Swagger Docket configuration look like? – Amphibole
I have edited the post to add the Swagger configuration – Drainpipe
L
36

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.)


For Springdoc see: How to hide endpoints from OpenAPI documentation with Springdoc

Liddell answered 6/3, 2019 at 20:44 Comment(0)
A
15

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;
Aubergine answered 6/4, 2020 at 8:19 Comment(0)
W
9

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;
    }
}
Weber answered 13/5, 2019 at 15:19 Comment(1)
I resolved hiddon the operation too. By my docs was in a interface. A recommend it. – Kermit
E
5

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.
}
Eastbound answered 3/3, 2020 at 17:52 Comment(1)
Thank you. And it is found here import io.swagger.v3.oas.annotations.Hidden; – Collywobbles
I
4

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.

Instauration answered 12/1, 2022 at 16:28 Comment(0)
E
-8

Another option is to just remove the @Api completely, and your controller and its methods shouldn't be picked up by swagger.

Empyema answered 20/11, 2019 at 0:47 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.