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

How do I ignore APIs with swagger-springmvc? #80

Closed
agentgonzo opened this issue May 14, 2013 · 14 comments
Closed

How do I ignore APIs with swagger-springmvc? #80

agentgonzo opened this issue May 14, 2013 · 14 comments
Labels

Comments

@agentgonzo
Copy link

I've got three controllers in my project:

/
/roles
/services

The / controller is just for providing a health-check endpoint and version info, and so I don't want this to be listed in the Swagger docs (but don't want to keep it as an HTTP get on the main tomcat context is the handiest way to find version info). Is there an easy way to get swagger to ignore this Controller? I've found some stuff about endpoint filters but can't figure out how to get it to work.

    <bean class="com.mangofactory.swagger.SwaggerConfigurationExtension">
            ...
            <property name="endpointFilters">
                <list>
                    <value > /  </value>
                </list>
            </property>
    </bean>

Any help gladly appreciated.

@dilipkrish
Copy link
Member

@agentgonzo which version of the library are you using? In 0.5.0 its much simpler to do stuff

Just create a subclass of the ExtensibilityModel and pull it in your spring configuration. Depending on how you've got your server configured you might need to use context:annotation configuration.

See an example over at the example project. The spring configuration needs to look like so and your extensibility bean might look something like this.

You might need to override the customizeExcludedResources method to do what you need. just add "/" as an entry to that list.

@agentgonzo
Copy link
Author

I'm using 0.4.2, the latest version. 0.5.0 isn't in the maven repos.

On 14 May 2013, at 18:04, Dilip Krishnan notifications@github.com wrote:

Which version are you using?

In 0.5.0 the extensibility model has become much simpler. Just create a bean like so, and it gives you the hooks to override anything thats overridable. In your case you need to override the customizeExcludedResources method.

We've moved to java based configuration. You can pull in the extensibility via configuration. See the example spring config over at the example project.


Reply to this email directly or view it on GitHub.

@kldavis4
Copy link

@agentgonzo I just download 0.5.0 yesterday, so it is out there

@dilipkrish
Copy link
Member

@agentgonzo
Copy link
Author

Oh, thanks. I was looking on
http://mvnrepository.com/artifact/com.mangofactory/swagger-springmvc

Is mvnrepository.org a mirror then that's out of date - that's what I've
always used in the past.

'gonz

On 14/05/2013 18:20, Dilip Krishnan wrote:

@agentgonzo https://github.com/agentgonzo it should be there
http://search.maven.org/#search%7Cga%7C1%7Cswagger-springmvc


Reply to this email directly or view it on GitHub
#80 (comment).

@lucasmorano
Copy link

I've created myself another annotation @ApiIncludeController once that annotation is present in at least one controller my ExtensibilityModule filter controllers without that annotation excluding all of them, maybe that would be a good idea for you..

@dilipkrish
Copy link
Member

@lucassagarana There is already support for @ApiInclude and @ApiIgnore. So you shouldnt need to do that.

@lucasmorano
Copy link

@dilipkrish but the target to that is Method, so i cannot use it on the scope of my class to include everything..

@Glamdring
Copy link

One could really get lost in the extensibility module's methods, especially since they have no documentation. What does List[Filter[DocumentationEndPoint]] mean, and how should the filter look like, if we want to keep just a predefined list of controller?

@Glamdring
Copy link

In fact, I didn't find a way to use an include-only strategy. DocumentationEndPoint filters cannot remove endpoints from the Documentation, and a Documentation Filter is invoked before the endpoints are added, so you can't remove them there either.
I managed to use a custom Documentation object in a Documentation Filter and replaced it with reflection in the FilterContext, but that's way too hacky. There should be another way.

@dilipkrish
Copy link
Member

@Glamdring There are a lot of extensibility points.. The challenge is to choose the right one for the job :). Agreed, that the documentation is fairly sparse, but hopefully the examples in the example project serve as a replacement for that. Also some of the issues marked as questions are meant to build up faqs over time.

Going from simple to complex here are the tools at your disposal.

  • The @ApiIgnore and @ApiInclude are the simplest way to control what apis are included or ignored. By default everything is marked as included unless it is excluded. It provides fine grained control over whats included or excluded.
  • The next extensibility point is the customizeExcluded resources.
    This is used mostly if you dont want to clutter the controllers with annotations from third party libraries. Here you can add all the endpoint urls... for e.g. if you have an endpoint http://hostname/web-application/pet. You can add to the list "/pet" and automatically the urls will be ignored. Every RequestMapping is automatically included unless it is in this list.
  • Finally if the above extensibility points dont make sense you could simply take what is generated and transform the results. Create a bean that implements a DocumentationTransformer and override the applyTransformation. This will give you ultimate control over what you want to render.
  • Least desirable is to implement your own Filter<Documentation> like you possibly did and remove the endpoints you dont care about.

I suppose the name of the type Filter is throwing you off. Its Filter used in the sense of Pipes-and-filters pattern, and not to filter the documentation endpoints from whats rendered! So a filter is just an part of the pipeline that can augment the type the filter is acting on. So an implementation of Filter<DocumentationEndPoint> augments a documentation endpoint object thats passed into it. You shouldn't need to implement a filter unless you have a need to override the documentation in a specific way that the library does not know about. For e.g. if you're using custom annotations for validation and want to handle how those are rendered.

You shouldn't need to use reflection at all. I'd be curious what your use case is. Aside from the library documentation, if the apis are not leading you to the pit of success :) thats something I'd love to know about, so that it can be addressed from a api usability standpoint. It would be useful if you can share what you're trying to do and how you're solving the problem. That way if theres a simpler solution I might be able to suggest alternatives.

@Glamdring
Copy link

Thanks. The I'll check the Transformation option.

What I want to do is simply expose one or several controllers as an API, and have all other controllers as internal. I don't want to split it in two projects (which might be generally a good idea), because the project is small and that would be an overhead.

So, a single projects, with 1-2 controllers with a public API and the rest used internally bu the web app. Pretty standard, I think.

The @ApiIgnore is good, but as mentioned above it works on a method level, rather than on controller level. As far as I saw, customizeExcluded requires an explicit list, you can't use a pattern e.g /api/**. And having to manually ignore/exclude each individual method (and each future method) is tedious.

Ideally, I would like to have a configuration switch that excludes everything by default and includes only @ApiInclude methods, or even better - @ApiIncludeClass* classes.

@adrianbk
Copy link
Member

We had a similar requirement and excluded everything without a swagger
annotation. Its not ideal but its one way of doing it.

protected void customizeExcludedResources(List excludedResources) {

//Only Controllers with the swagger Api annotations should be included
Map<RequestMappingInfo, HandlerMethod> handlerMethods =

this.requestMappingHandlerMapping.getHandlerMethods();
if (null == handlerMethods) {
return;
}

for (Map.Entry<RequestMappingInfo, HandlerMethod> entry :

handlerMethods.entrySet()) {
HandlerMethod handlerMethod = entry.getValue();
boolean hasAnnotation = false;
Class beanType = handlerMethod.getBeanType();
Annotation[] declaredAnnotations = beanType.getDeclaredAnnotations();
if (null != declaredAnnotations) {
for (Annotation a : declaredAnnotations) {
if (isSwaggerAnnotation(a)) {
hasAnnotation = true;
break;
}
}
}
if (!hasAnnotation) {
excludedResources.addAll(controllerUris(beanType));
}
}
}
On 13/01/2014 5:34 PM, "Bozhidar Bozhanov" notifications@github.com wrote:

Thanks. The I'll check the Transformation option.

What I want to do is simply expose one or several controllers as an API,
and have all other controllers as internal. I don't want to split it in two
projects (which might be generally a good idea), because the project is
small and that would be an overhead.

So, a single projects, with 1-2 controllers with a public API and the rest
used internally bu the web app. Pretty standard, I think.

The @ApiIgnore is good, but as mentioned above it works on a method level,
rather than on controller level. As far as I saw, customizeExcluded
requires an explicit list, you can't use a pattern e.g /api/**. And having
to manually ignore/exclude each individual method (and each future method)
is tedious.

Ideally, I would like to have a configuration switch that excludes
everything by default and includes only @ApiInclude methods, or even better

  • @ApiIncludeClass* classes.


Reply to this email directly or view it on GitHubhttps://github.com//issues/80#issuecomment-32147946
.

@Glamdring
Copy link

@dilipkrish btw, the transformer I registered isn't picked up for some reason, I don't have time to investigate further
@adrianbk yes, indeed, something like that would be perfect.

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

6 participants