Skip to content
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

@RepositoryRestController not being parsed during API documentation build process #2656

Open
predrag-viceic opened this issue Sep 3, 2018 · 15 comments
Labels

Comments

@predrag-viceic
Copy link

predrag-viceic commented Sep 3, 2018

Hello,

This is a new feature request originating from this issue:

#2127

@RepositoryRestController is used to customize/overwrite Spring-Data-Rest generated endpoints, as explained here:

https://docs.spring.io/spring-data/rest/docs/current/reference/html/#customizing-sdr.overriding-sdr-response-handlers

These are however not picked up by the Springfox documentation building process.

If you clone the following repo:

https://github.com/predrag-viceic/Springfox2127

and run it with gradle bootRun, you can see that the ui on localhost:8080/swagger-ui.html doesn't show the http://localhost:8080/myTestBeans/count_entities endpoint (although it exists).

The other Spring-Data-Rest endpoints are correctly documented.

I would be gratefull if this annotation could be added in the API documentation!

Many thanks,
Predrag

@dilipkrish
Copy link
Member

@predrag-viceic thanks for a detailed bug report!

@computerlyrik
Copy link

computerlyrik commented Oct 9, 2018

+1

@predrag-viceic any workaround found? Any way to add the controller info to the swagger-doc manually via code or perhaps via annotation?

@predrag-viceic
Copy link
Author

No not really..replaced with @RestController whenever possible otherwise I just live without everything being documented automatically..

@drenda
Copy link

drenda commented Oct 15, 2018

Any workaround for this? Thanks

@computerlyrik
Copy link

as @predrag-viceic stated above @RestController will trigger e.g. doc-generation.
I am using it additonally to @RepositoryRestController .

Could have unknown side-effects though...

@drenda
Copy link

drenda commented Oct 15, 2018

as @predrag-viceic stated above @RestController will trigger e.g. doc-generation.
I am using it additonally to @RepositoryRestController .

Could have unknown side-effects though...

I see. Thanks for the hint.

@drognisep
Copy link

as @predrag-viceic stated above @RestController will trigger e.g. doc-generation.
I am using it additonally to @RepositoryRestController .

Could have unknown side-effects though...

One of the side-effects I've noticed is that using the @RestController annotation can effectively block the auto-generated spring-data-rest endpoints from being resolved.

See this stackoverflow question for a detailed explanation of the problem.

Is there any known timeline for this being resolved?

@drognisep
Copy link

@dilipkrish I don't know if you saw my previous comment, but the proposed workaround of using @RestRepository won't work for all cases. What kind of effort would be involved to support Spring Data Rest annotations in the same way as MVC annotations? Would it impact other aspects of the plugin?

@jaderss
Copy link

jaderss commented May 8, 2019

Is this project still alive?

@drognisep
Copy link

@jaderss I'm not sure, honestly, it looks like @dilipkrish hasn't been super active recently. It might be worth looking into one of the many forks, but there are sooo many.

@bogaertg
Copy link

news ?

@kabasakalis
Copy link

kabasakalis commented Aug 21, 2019

as @predrag-viceic stated above @RestController will trigger e.g. doc-generation.
I am using it additonally to @RepositoryRestController .

Could have unknown side-effects though...

One of which is that you have duplicate endpoints.

@kabasakalis
Copy link

Spring Data Rest is so popular that I am (negatively) amazed by the fact that springfox will ignore @RepositroryRestController for swagger generation. Are there any forks of this projects or other projects that solve this issue? I will appreciate you help.

@drognisep
Copy link

Spring Data Rest is so popular that I am (negatively) amazed by the fact that springfox will ignore @RepositroryRestController for swagger generation. Are there any forks of this projects or other projects that solve this issue? I will appreciate you help.

There are plenty of forks, but I don't know about the quality of any of them, unfortunately. :(
It's mainly due to this issue that we're moving in a different direction for REST documentation. Spring REST docs has been... rather painful, but at least it's supported.

@Aqu1nt
Copy link

Aqu1nt commented Jun 2, 2020

So i've also stumbled across this issue, and came up with the following solution which seems to work pretty well, although its a bit hacky.

It just creates a simple RequestHandlerProvider which will get all RepositoryRestController and finds all RequestMapping methods and then creates a standard WebMvcRequestHandler for every "custom spring data rest method".

(Its written in Kotlin, but the conversion to Java should be pretty straight forward)

import org.springframework.context.ConfigurableApplicationContext
import org.springframework.core.annotation.AnnotationUtils
import org.springframework.data.rest.webmvc.RepositoryRestController
import org.springframework.stereotype.Component
import org.springframework.util.ReflectionUtils
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.method.HandlerMethod
import org.springframework.web.servlet.mvc.method.RequestMappingInfo
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
import springfox.documentation.RequestHandler
import springfox.documentation.spi.service.RequestHandlerProvider
import springfox.documentation.spring.web.WebMvcRequestHandler
import springfox.documentation.spring.web.readers.operation.HandlerMethodResolver
import java.lang.reflect.Method

@Component
class SpringfoxRepositoryRestControllerProvider(private val context: ConfigurableApplicationContext,
                                                private val methodResolver: HandlerMethodResolver,
                                                private val requestMappingHandlerMapping: RequestMappingHandlerMapping): RequestHandlerProvider {

    private val getMappingForMethod = RequestMappingHandlerMapping::class.java.getDeclaredMethod("getMappingForMethod", Method::class.java, Class::class.java)

    init {
        getMappingForMethod.isAccessible = true
    }

    override fun requestHandlers(): List<RequestHandler> {
        val repositoryRestControllers = context.getBeansWithAnnotation(RepositoryRestController::class.java)
        return repositoryRestControllers.values.flatMap { controller ->
            findRequestMappingMethods(controller).map { requestMappingMethod ->
                WebMvcRequestHandler(
                        "",
                        methodResolver,
                        buildRequestMappingInfo(controller, requestMappingMethod),
                        HandlerMethod(controller, requestMappingMethod)
                )
            }
        }
    }

    private fun buildRequestMappingInfo(controller: Any, requestMappingMethod: Method): RequestMappingInfo {
        return getMappingForMethod.invoke(requestMappingHandlerMapping, requestMappingMethod, controller::class.java) as RequestMappingInfo
    }

    private fun findRequestMappingMethods(controller: Any): List<Method> {
        val mappingMethods = mutableListOf<Method>()
        ReflectionUtils.doWithMethods(controller::class.java) { method ->
            if (AnnotationUtils.findAnnotation(method, RequestMapping::class.java) != null) {
                mappingMethods.add(method)
            }
        }
        return mappingMethods
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants