After solving Using Springfox to document jax-rs services in a Spring app, I now find that SpringFox's JSON reply doesn't 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's 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 in a properties file:
swagger.resourcePackage=org.myapp
Swagger is configured to find the implementation classes using the reflective jax-rs 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's 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's a sample class with the 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's 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 isn't it exposing the API? Would using the wordnik swagger library solve this, or improve the solution?