Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to exclude OPTIONS, HEAD and PATCH method from spring-data-rest entityController

I am using spring-data-rest-webmvc:jar:2.5.3.RELEASE to write REST API and rendered the resources in springfox-data-rest-2.6.0. The swagger renders all methods resides in RestEntityController. I excluded some methods in repository level by using @RestResource(exported = false). But swagger loads all other HTTP methods like OPTIONS, HEAD and PATCH which I am unable to exclude from RepositoryRestResource.

How to render my swagger with clean resource that include only my CRUD and search methods? Need to support this either in using spring-data-rest configuration or using springfox configuration.

like image 380
Achaius Avatar asked Oct 07 '16 12:10

Achaius


People also ask

What does the @RepositoryRestResource annotation do?

The @RepositoryRestResource annotation is optional and is used to customize the REST endpoint. If we decided to omit it, Spring would automatically create an endpoint at “/websiteUsers” instead of “/users“. That's it! We now have a fully-functional REST API.

Why is Spring Data REST not recommended in real world applications?

It is not recommended in real-world applications as you are exposing your database entities directly as REST Services. While designing RESTful services, the two most important things that we consider are the domain model and the consumers. But, while using Spring Data REST, none of these parameters are considered.

What is @RepositoryRestController?

Annotation Type RepositoryRestControllerAnnotation to demarcate Spring MVC controllers provided by Spring Data REST. Allows to easily detect them and exclude them from standard Spring MVC handling.

What is collectionResourceRel?

and collectionResourceRel is described: The rel value to use when generating links to the collection resource.


2 Answers

After delving into the springfox documentation and discarding some dead end ideas, I come up with two solutions that might solve your issue. Apply and mix them according to your needs.

Hint #1 - Filter by using the RequestHandlerSelectors

Tell springfox which method endpoints you would like to show in the swagger-ui. Therefore you can setup your RequestHandlerSelector to scan your whole application, a specific package or classes and methods that you have annotated with a shared annotion.

//Example for the method scan based on springfox's @ApiOperation annotation

@Bean
public Docket api() {    
    return new Docket(DocumentationType.SWAGGER_2)          
      .select()                                       
      .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any())
      .build();
}



// Within your dao or repository class
public interface QueuedMessageDao extends CrudRepository<QueuedMessage, Integer> {
    @ApiOperation(value = "This method finds all messages that are queued with the recipient's email address")
    List<QueuedMessage> findByRecipientEmail(String email); 
}

This will cut off a lot of spring-data-rest overhead from your swagger documentation. But you will still (surprisingly) see unwanted HTTP methods in your swagger-ui, like the GET, HEAD and OPTIONS methods for your technical /<entity>/search endpoint. I say technical, because these endpoints are intended to discover other endpoints only, they don't serve you with data from your entities.

Hint #2 - Filter by using the PathSelectors

In case you want to get rid of the technical /<entity>/search endpoints in swagger, you can exclude them using a regex that filters out all search endpoints but keeps the endpoints that are relevant for you. To still have a business endpoint for searches within your entities, you just need to set up an implicit GET endpoint.

//Example for the method scan based on springfox's @ApiOperation annotation

@Bean
public Docket api() {    
    return new Docket(DocumentationType.SWAGGER_2)          
      .select()                                       
      .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.regex("^(?!(/.*(/search)$)).*$"))
      .build();
}

// Within your dao or repository class
public interface QueuedMessageDao extends CrudRepository<QueuedMessage, Integer> {

    @ApiOperation(value = "this generates a business search endpoint")
    List<QueuedMessage> findById(int id);

    @ApiOperation(value = "This method finds all messages that are queued with the recipient's email address")
    List<QueuedMessage> findByRecipientEmail(String email); 
}

Now you got rid of the search endpoint but still have a business search in your swagger documentation. Hope this helps!

like image 80
mika Avatar answered Nov 15 '22 08:11

mika


I had the same problem as you, I just wanted to show CRUD operations to my clients through Swagger UI. After digging in Springfox documentation,I created my own Predicate to filter endpoints only for CRUD operations, checking the requested Method.

@Bean
public Docket api() { 
    return new Docket(DocumentationType.SWAGGER_2)  
        .select()                                  
            .apis(customRequestHandlers())
            .build();
}

private Predicate<RequestHandler> customRequestHandlers() {     
    return new Predicate<RequestHandler>() {
        @Override
        public boolean apply(RequestHandler input) {
            Set<RequestMethod> methods = input.supportedMethods();
            return methods.contains(RequestMethod.GET)  
                || methods.contains(RequestMethod.POST)
                || methods.contains(RequestMethod.PUT)
                || methods.contains(RequestMethod.DELETE);
        }
    };
}
like image 25
alonso_50 Avatar answered Nov 15 '22 09:11

alonso_50