Unit | Functional | Coverage |
---|---|---|
An upgrade to the swagger-springmvc project to the latest Swagger specification (1.2).
The swagger specification upgrade to 1.2 has several feature additions and has also refactored it's core model structure.
See swagger-core
The demo/sample application is built off of swagger-ui tag v2.0.4
There are currently some features not fully supported:
- Model generation - work in progress to modularize the model generation from prior versions of swagger-springmvc. This version uses the model generation that ships with swagger-core which is not as powerful when it comes to polymorphic models.
https://github.com/adrianbk/swagger-springmvc-demo
<repositories>
<repository>
<id>sonatype-snapshots</id>
<name>Sonatype</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>0.8.4-SNAPSHOT</version>
</dependency>
or maven central: http://repo1.maven.org/maven2/
<repositories>
<repository>
<id>sonatype-snapshots</id>
<name>Sonatype</name>
<url>https://oss.sonatype.org/content/repositories/releases/</url>
</repository>
</repositories>
<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>0.8.3</version>
</dependency>
- Authorization types: (OAuth, ApiKey, BasicAuth).
- ApiInfo: info, title, licencing, etc.
- Http media types (produces/consumes).
- Model annotation changes.
- resource & base path changes.
- Swagger core library has upgraded to scala 2.10.0. For more detail see: https://github.com/wordnik/swagger-core/wiki/1.2-transition.
- Spring 3.2.x or above
- scala lib 2.10.0
- jackson 2.1.5 (older/newer versions may work)
By no means is the documentation great but the project has plenty of tests and we're slowly chipping away at the documentation. The latest javadocs are available here. Contributions that add to test coverage and documentation is always welcome! :)
Change Log is available for the changes since 0.8.3
- Remove the following autowired fields in your spring configuration
@Autowired
private SpringSwaggerModelConfig springSwaggerModelConfig;
- Add the following autowired fields in your spring configuration
@Autowired
private ModelProvider modelProvider;
- Make sure any customizations to the object mapper are appropriately added in an ObjectMapper bean definition
/**
* Object mapper.
*
* @return the configured object mapper
*/
@Bean
public ObjectMapper objectMapper() {
//This is the opportunity to override object mapper behavior
return new ObjectMapper();
}
- Configure the swaggerApiResourceListing bean with the model provider that is autowired or provide your own implementation
// Set the model provider, uses the default autowired model provider.
swaggerApiResourceListing.setModelProvider(modelProvider);
- Configure the blah bean with an implementation of the resource grouping strategy
//How to group request mappings to ApiResource's typically by spring controller classes. This is a hook to provide
// a custom implementation of the grouping strategy. By default we use SpringGroupingStrategy. An alternative is
// to use ClassOrApiAnnotationResourceGrouping to group using Api annotation.
apiListingReferenceScanner.setResourceGroupingStrategy(springSwaggerConfig.defaultResourceGroupingStrategy());
- Allows configuration of default response messages based on HTTP methods which are displayed on all api operations on swagger-ui
E.g. Default response messages for HTTP GET methods
responses.put(GET, asList(
new ResponseMessage(OK.value(), OK.getReasonPhrase(), toOption(null)),
new ResponseMessage(NOT_FOUND.value(), NOT_FOUND.getReasonPhrase(), toOption(null)),
new ResponseMessage(FORBIDDEN.value(), FORBIDDEN.getReasonPhrase(), toOption(null)),
new ResponseMessage(UNAUTHORIZED.value(), UNAUTHORIZED.getReasonPhrase(), toOption(null))
));
Configurable global ignored spring mvc controller method parameters/HandlerMethodArgumentResolver
's
Annotation classes can also be added here to ignore method parameters with a specific annotation.
E.g.
HashSet<Class> ignored = newHashSet();
ignored.add(ServletRequest.class);
ignored.add(ServletResponse.class);
ignored.add(HttpServletRequest.class);
ignored.add(HttpServletResponse.class);
ignored.add(BindingResult.class);
ignored.add(ServletContext.class);
- Configurable swagger type substitutions
E.g.
AlternateTypeProvider alternateTypeProvider = new AlternateTypeProvider();
TypeResolver typeResolver = new TypeResolver(); //dependency on com.fasterxml.classmate
// Add a rule that substitutes ResponseEntity<AnyClass> to AnyClass
// NOTE: WildcardType is an in-built type used for type substitutions of generic
// types
alternateTypeProvider.addRule(
newRule(typeResolver.resolve(ResponseEntity.class, WildcardType.class),
typeResolver.resolve(WildcardType.class)));
// Add a rule that substitutes LocalDate to Date
alternateTypeProvider.addRule(
newRule(typeResolver.resolve(LocalDate.class),
typeResolver.resolve(Date.class)));
//After setting up the custom provider wire it up by calling swaggerGlobalSettings.setAlternateTypeProvider
-
Configurable uri path providers by implementing
SwaggerPathProvider
-
Exclude controller methods based on annotations
E.g.
List<Class<? extends Annotation>> annotations = new ArrayList<Class<? extends Annotation>>();
annotations.add(ApiIgnore.class);
- Flexible Inclusion or exclusion of paths using regex expressions. Make sure the include patterns apply
List<String> DEFAULT_INCLUDE_PATTERNS = Arrays.asList(new String[]{
"/business.*",
"/some.*",
"/contacts.*"
});
web application context xml config
<!-- Enable scanning of spring @Configuration classes -->
<context:annotation-config/>
<!-- Enable the default documentation controller-->
<context:component-scan base-package="com.mangofactory.swagger.controllers"/>
<!-- Pick up the bundled spring config. Not really required if you're already importing the configuration bean
as part of an application specific configuration bean via the previous component scan-->
<context:component-scan base-package="com.mangofactory.swagger.configuration"/>
Configuration is slightly verbose but on the upside it provides several hooks into the library.
- Place the following into a spring @Configuration java class or see: The Sample App Configuration
/**
*
* Autowire the bundled swagger config
*/
@Autowired
private SpringSwaggerConfig springSwaggerConfig;
@Autowired
private ModelProvider modelProvider;
/**
* Adds the jackson scala module to the MappingJackson2HttpMessageConverter registered with spring
* Swagger core models are scala so we need to be able to convert to JSON
* Also registers some custom serializers needed to transform swagger models to swagger-ui required json format
*/
@Bean
public JacksonScalaSupport jacksonScalaSupport() {
JacksonScalaSupport jacksonScalaSupport = new JacksonScalaSupport();
//Set to false to disable
jacksonScalaSupport.setRegisterScalaModule(true);
return jacksonScalaSupport;
}
/**
* Object mapper.
*
* @return the configured object mapper
*/
@Bean
public ObjectMapper objectMapper() {
//This is the opportunity to override object mapper behavior
return new ObjectMapper();
}
/**
* Global swagger settings
*/
@Bean
public SwaggerGlobalSettings swaggerGlobalSettings() {
SwaggerGlobalSettings swaggerGlobalSettings = new SwaggerGlobalSettings();
swaggerGlobalSettings.setGlobalResponseMessages(springSwaggerConfig.defaultResponseMessages());
// This is where we add types to ignore (or use the default provided types)
swaggerGlobalSettings.setIgnorableParameterTypes(springSwaggerConfig.defaultIgnorableParameterTypes());
// This is where we add type substitutions (or use the default provided alternates)
swaggerGlobalSettings.setAlternateTypeProvider(springSwaggerConfig.defaultAlternateTypeProvider());
return swaggerGlobalSettings;
}
/**
* API Info as it appears on the swagger-ui page
*/
private ApiInfo apiInfo() {
ApiInfo apiInfo = new ApiInfo(
"Demo Spring MVC swagger 1.2 api",
"Sample spring mvc api based on the swagger 1.2 spec",
"http://en.wikipedia.org/wiki/Terms_of_service",
"[email protected]",
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0.html"
);
return apiInfo;
}
/**
* Configure a SwaggerApiResourceListing for each swagger instance within your app. e.g. 1. private 2. external apis
* Required to be a spring bean as spring will call the postConstruct method to bootstrap swagger scanning.
*
* @return
*/
@Bean
public SwaggerApiResourceListing swaggerApiResourceListing() {
//The group name is important and should match the group set on ApiListingReferenceScanner
//Note that swaggerCache() is by DefaultSwaggerController to serve the swagger json
SwaggerApiResourceListing swaggerApiResourceListing = new SwaggerApiResourceListing(springSwaggerConfig.swaggerCache(), SWAGGER_GROUP);
//Set the required swagger settings
swaggerApiResourceListing.setSwaggerGlobalSettings(swaggerGlobalSettings());
//Use a custom path provider or springSwaggerConfig.defaultSwaggerPathProvider()
swaggerApiResourceListing.setSwaggerPathProvider(demoPathProvider());
//Supply the API Info as it should appear on swagger-ui web page
swaggerApiResourceListing.setApiInfo(apiInfo());
// Set the model provider, uses the default autowired model provider.
swaggerApiResourceListing.setModelProvider(modelProvider);
//Global authorization - see the swagger documentation
swaggerApiResourceListing.setAuthorizationTypes(authorizationTypes());
//Sets up an auth context - i.e. which controller request paths to apply global auth to
swaggerApiResourceListing.setAuthorizationContext(authorizationContext());
//Every SwaggerApiResourceListing needs an ApiListingReferenceScanner to scan the spring request mappings
swaggerApiResourceListing.setApiListingReferenceScanner(apiListingReferenceScanner());
return swaggerApiResourceListing;
}
@Bean
/**
* The ApiListingReferenceScanner does most of the work.
* Scans the appropriate spring RequestMappingHandlerMappings
* Applies the correct absolute paths to the generated swagger resources
*/
public ApiListingReferenceScanner apiListingReferenceScanner() {
ApiListingReferenceScanner apiListingReferenceScanner = new ApiListingReferenceScanner();
//Picks up all of the registered spring RequestMappingHandlerMappings for scanning
apiListingReferenceScanner.setRequestMappingHandlerMapping(springSwaggerConfig.swaggerRequestMappingHandlerMappings());
//Excludes any controllers with the supplied annotations
apiListingReferenceScanner.setExcludeAnnotations(springSwaggerConfig.defaultExcludeAnnotations());
//How to group request mappings to ApiResource's typically by spring controller clesses or @Api.value()
apiListingReferenceScanner.setResourceGroupingStrategy(springSwaggerConfig.defaultResourceGroupingStrategy());
//Path provider used to generate the appropriate uri's
apiListingReferenceScanner.setSwaggerPathProvider(demoPathProvider());
//Must match the swagger group set on the SwaggerApiResourceListing
apiListingReferenceScanner.setSwaggerGroup(SWAGGER_GROUP);
//Only include paths that match the supplied regular expressions
apiListingReferenceScanner.setIncludePatterns(DEFAULT_INCLUDE_PATTERNS);
return apiListingReferenceScanner;
}
/**
* Example of a custom path provider
*/
@Bean
public DemoPathProvider demoPathProvider() {
DemoPathProvider demoPathProvider = new DemoPathProvider();
demoPathProvider.setDefaultSwaggerPathProvider(springSwaggerConfig.defaultSwaggerPathProvider());
return demoPathProvider;
}
##Development
- Running tests with coverage:
mvn test jacoco:check
Report directory: \target\site\jacoco-ut
Coverage only
mvn jacoco:check
Deploy to local nexus
mvn deploy
-Coverage Help
mvn org.jacoco:jacoco-maven-plugin:0.6.3.201306030806:check
Skipping coverage
mvn deploy -Djacoco.skip=true
Pre Commit or before submitting a pull request
mvn verify
Copyright 2012 Marty Pitt - @martypitt, Dilip Krishnan - @dilipkrish, Adrian Kelly - @adrianbk,
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.