Open yissachar opened 9 years ago
+1
If you are trying to onboard legacy service implementations to swagger, going back and annotating everything can be a pain...and really isn't necessary for basic documentation needs.
I've done some work locally to make this possible for spring mvc projects, using a POM configuration boolean "requireSwaggerAnnotations = false", and created an extension of the spring reader which works without swagger annotations. It's most likely possible to do the same with the jaxrs reader, but this is a pretty big design decision that is up to @who and @kongchen .
Ok, it seems the Reader from latest swagger-jaxrs(1.5.4) can use JAX-RS annotations to generate swagger spec, as long as you put one class level annotation '@Api' there.
I think a better approach is to have 'swagger-maven-plugin' to support Reader from swagger-jaxrs, instead of sub class com.github.kongchen.swagger.docgen.reader.ClassSwaggerReader. No point to include swagger-maven-plugin in dependencies, just for a customized reader.
sample code for using swagger-jaxrs reader:
package com.github.kongchen.swagger.docgen.reader;
import com.github.kongchen.swagger.docgen.GenerateException;
import com.github.kongchen.swagger.docgen.LogAdapter;
import com.wordnik.jaxrs.SubResource;
import edu.emory.mathcs.backport.java.util.Collections;
import io.swagger.jaxrs.Reader;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import org.testng.annotations.Test;
import java.util.Map;
import java.util.Set;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
public class JaxrsReaderTest {
@Test
public void testRead() throws Exception {
LogAdapter LOG = null;
JaxrsReader reader = new JaxrsReader(new Swagger(), LOG);
Swagger swagger = reader.read(SubResource.class);
Map<String, Path> paths = swagger.getPaths();
assertThat(paths, is(nullValue()));
}
@Test
public void testMyRead() throws Exception {
MyReader reader = new MyReader();
Swagger swagger = reader.read(Collections.singleton(SubResource.class));
Map<String, Path> paths = swagger.getPaths();
assertThat(paths.keySet().toArray(new String[2]), is(new String[]{"/resources", "/resources/sub"}));
}
public static class MyReader implements ClassSwaggerReader {
@Override
public Swagger read(Set<Class<?>> classes) throws GenerateException {
Reader reader = new Reader(null);
return reader.read(classes);
}
}
}
package com.wordnik.jaxrs;
import io.swagger.annotations.Api;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
@Path("/resources")
@Api(value = "/resources")
public class SubResource {
@GET
public Response resources() {
return Response.ok().build();
}
@Path("/sub")
@GET
public Response sub() {
return Response.ok().build();
}
}
+1 As ShijunK states, this is already possible. It's pretty easy to achieve in using a jax-rs-doclet in Maven/Dropwizard. Since Dropwizard is based on Jersey, I would imagine it would be possible in your case.
+1
If you are trying to onboard legacy service implementations to swagger, going back and annotating everything can be a pain...and really isn't necessary for basic documentation needs.
I've done some work locally to make this possible for spring mvc projects, using a POM configuration boolean "requireSwaggerAnnotations = false", and created an extension of the spring reader which works without swagger annotations. It's most likely possible to do the same with the jaxrs reader, but this is a pretty big design decision that is up to @who and @kongchen .
@tedleman , can you share your implementation with customized spring reader worked for you? I also wanted to generated swagger YAML but do not want to go back to add annotations.
@who , @kongchen , this looks obvious requirement to support, are there any existing implementation available or any future plan to support this? My legacy code has @Path annotations from Javax.wa.rs.** and dont wanted to put another @Api annotations.
Ok, it seems the Reader from latest swagger-jaxrs(1.5.4) can use JAX-RS annotations to generate swagger spec, as long as you put one class level annotation '@Api' there.
I think a better approach is to have 'swagger-maven-plugin' to support Reader from swagger-jaxrs, instead of sub class com.github.kongchen.swagger.docgen.reader.ClassSwaggerReader. No point to include swagger-maven-plugin in dependencies, just for a customized reader.
sample code for using swagger-jaxrs reader:
package com.github.kongchen.swagger.docgen.reader; import com.github.kongchen.swagger.docgen.GenerateException; import com.github.kongchen.swagger.docgen.LogAdapter; import com.wordnik.jaxrs.SubResource; import edu.emory.mathcs.backport.java.util.Collections; import io.swagger.jaxrs.Reader; import io.swagger.models.Path; import io.swagger.models.Swagger; import org.testng.annotations.Test; import java.util.Map; import java.util.Set; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; public class JaxrsReaderTest { @Test public void testRead() throws Exception { LogAdapter LOG = null; JaxrsReader reader = new JaxrsReader(new Swagger(), LOG); Swagger swagger = reader.read(SubResource.class); Map<String, Path> paths = swagger.getPaths(); assertThat(paths, is(nullValue())); } @Test public void testMyRead() throws Exception { MyReader reader = new MyReader(); Swagger swagger = reader.read(Collections.singleton(SubResource.class)); Map<String, Path> paths = swagger.getPaths(); assertThat(paths.keySet().toArray(new String[2]), is(new String[]{"/resources", "/resources/sub"})); } public static class MyReader implements ClassSwaggerReader { @Override public Swagger read(Set<Class<?>> classes) throws GenerateException { Reader reader = new Reader(null); return reader.read(classes); } } } package com.wordnik.jaxrs; import io.swagger.annotations.Api; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Response; @Path("/resources") @Api(value = "/resources") public class SubResource { @GET public Response resources() { return Response.ok().build(); } @Path("/sub") @GET public Response sub() { return Response.ok().build(); } }
@ShijunK , can you share your complete working example including pom.xml if any customized approach worked for you? I am not sure how to customize Readers to use swagger-jaxrs library and don't have much resources to figure out.
I am using this with a Jersey project and it seems odd that I am forced to double annotate all my methods; once for Jersey and once for Swagger. I am not using any of the additional documentation that Swagger provides - I am simply using Api and ApiOperation annotations to indicate the methods that are part of my API. As far as I can tell it should be possible to do this by just looking at the Jersey Path annotations.
Is this use case not supported? It's not the end of the world if I have to double annotate everything but it just seems silly.