After the solution Using Springfox to document jax-rs services in a Spring application, I now find that the SpringFox JSON response does not show any APIs:
{ "swagger": "2.0", "info": { "description": "Some description", "version": "1.0", "title": "My awesome API", "contact": { "name": " my-email@domain.org " }, "license": {} }, "host": "localhost:9090", "basePath": "/myapp" }
Here is springfox-servlet.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean class="com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON" /> <bean class="com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider" /> <bean class="com.wordnik.swagger.jaxrs.listing.ResourceListingProvider" /> </beans>
This is the properties file:
swagger.resourcePackage=org.myapp
Swagger is configured to look for implementation classes using the jax-rs reflective scanner:
@Component public class SwaggerConfiguration { @Value("${swagger.resourcePackage}") private String resourcePackage; @PostConstruct public void init() { ReflectiveJaxrsScanner scanner = new ReflectiveJaxrsScanner(); scanner.setResourcePackage(resourcePackage); ScannerFactory.setScanner(scanner); ClassReaders.setReader(new DefaultJaxrsApiReader()); SwaggerConfig config = ConfigFactory.config(); config.setApiVersion(apiVersion); config.setBasePath(basePath); } public String getResourcePackage() { return resourcePackage; } public void setResourcePackage(String resourcePackage) { this.resourcePackage = resourcePackage; } }
Here is the documentation configuration:
@Configuration @EnableSwagger2 public class ApiDocumentationConfiguration { @Bean public Docket documentation() { System.out.println("=========================================== Initializing Swagger"); return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build() .pathMapping("/") .apiInfo(metadata()); } @Bean public UiConfiguration uiConfig() { return UiConfiguration.DEFAULT; } private ApiInfo metadata() { return new ApiInfoBuilder() .title("My awesome API") .description("Some description") .version("1.0") .contact(" my-email@domain.org ") .build(); } }
And here is a sample class with api annotations:
@Api(value = "activity") @Service @Path("api/activity") @Produces({ MediaType.APPLICATION_JSON }) public class ActivityService { @Autowired private CommandExecutor commandExecutor; @Autowired private FetchActivityCommand fetchActivityCommand; @ApiOperation(value = "Fetch logged-in user activity", httpMethod = "GET", response = Response.class) @GET @Path("/mine") @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.APPLICATION_JSON) @Authorization(rejectionMessage = Properties.Authorization.NOT_LOGGED_IN_MESSAGE_PREFIX + "view your activities.") public List<Activity> listMyActivities(@Context HttpServletResponse response, @Context HttpServletRequest request) throws IOException { return buildActivityList(response, (UUID) request.getSession().getAttribute(Properties.Session.SESSION_KEY_USER_GUID)); } ... }
Why doesn't it expose the API? Will using the wordnik swagger library solve this problem or improve the solution?