kongchen / swagger-maven-plugin

JAX-RS & SpringMVC supported maven build plugin, helps you generate Swagger JSON and API document in build phase.
http://kongchen.github.io/swagger-maven-plugin/
Apache License 2.0
761 stars 450 forks source link

After upgrading to 3.1.1, the request object as gone missing #261

Open testn opened 8 years ago

testn commented 8 years ago

Basically this section has disappeared after I upgraded from 3.1.0 to 3.1.1

{ "in" : "body", "name" : "body", "required" : false, "schema" : { "$ref" : "#/definitions/MyObjectRequest" } }

who commented 8 years ago

@testn

Is this JAX-RS or SpringMVC mode? Would you be able to share your annotated method?

efonsell commented 8 years ago

I have the same issue, I'm using JAX-RS and the method is like this:

@ApiOperation(value = "Submit new foo", response = CreateFooResponse.class)
@ApiResponse(code = 201, message = "Foo was created")
public Response createFoo(@Valid CreateFooRequest req) {
  Foo foo = createFoo(req);
  int id = foo.id;
  return Response.created(URI.create(String.valueOf(id))).entity(foo).build();
}
laurentsorin commented 8 years ago

Hi,

Same issue for me in 3.1.2 and 3.1.3 ... Is there a workaround or a specific annotation ?

Thanks

laurentsorin commented 8 years ago

Just found a workaround : You need to add explicit @ApiParam annotation for body params (and all params now...) . ex :

Person addPerson(@ApiParam(value = "Person to add", required = true) Person person)

matteosilv commented 8 years ago

Other workaround:

import swagger-core-api in your project:

<groupId>io.swagger</groupId>
<artifactId>swagger-project</artifactId>
<version>1.5.6</version>

implement:

package com.your.project;

import java.util.Set;
public class ApiReader implements ClassSwaggerReader {

    @Override
    public Swagger read(Set<Class<?>> classes) throws GenerateException {
        Reader reader = new Reader(new Swagger());

        return reader.read(classes);
    }

}

configure the plugin with the option:

 <apiSource>
 ....
      <swaggerApiReader>com.your.project.ApiReader</swaggerApiReader>
      ....

this will proxy to the parser of the official swagger project

NutterzUK commented 8 years ago

This works a treat - thank you! It also solves some other problems I was having and gives a good guide on how to extend or override the reader. Many thanks.

matteosilv commented 8 years ago

You're welcome. I improved my previous implementation like this:

public class ApiReader extends AbstractReader implements ClassSwaggerReader {

    public ApiReader(Swagger swagger, LogAdapter LOG) {
        super(swagger, LOG);
        List<SwaggerExtension> extensions = Arrays.asList(new DefaultParameterExtension(),
                                                               new SwaggerJersey2Jaxrs());
        LOG.info("Replaced extension with: " + extensions);
        SwaggerExtensions.setExtensions(extensions);
    }

    @Override
    public Swagger read(Set<Class<?>> classes) throws GenerateException {
        Reader reader = new Reader(swagger);
        reader.read(classes);
        return reader.read(classes);
    }

}

This allows to propagate the Swagger instance already configured with the plugin parameters to the custom Reader implementation, and activate the default extension in swagger. Since SwaggerJersey2Jaxrs (I'm using jersey 2.x) is not bundled with the plugin dependencies you must include the dependency in the plugin configuration as follows:

<plugin>
    <groupId>com.github.kongchen</groupId>
    <artifactId>swagger-maven-plugin</artifactId>
    <version>${swagger.maven.version}</version>
    <executions>
        ... your executions
    </executions>
    <configuration>
        <apiSources>
            <apiSource>
                ...
                <info>
                    ....
                </info>
                ....
                <swaggerApiReader>com.eidosmedia.portal.apidoc.ApiReader</swaggerApiReader>
                <modelConverters>
                    <modelConverter>io.swagger.validator.BeanValidator</modelConverter>
                </modelConverters>
            </apiSource>
        </apiSources>
    </configuration>
    <dependencies>
        <!-- if you need hibernate validator -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-hibernate-validations</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <!-- if you need SwaggerJersey2Jaxrs -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-jersey2-jaxrs</artifactId>
            <!-- this version correspond to the one currently bundled in the plugin -->
            <version>1.5.4</version>
        </dependency>
    </dependencies>
</plugin>

I hope this can be helpfull for you all. Honestly, I didn't have the time to test it deeply, but if it integrates well, i would consider replacing the default parsing classes in the plugin with the ones in the official swagger core api. Maybe i'll branch the project and propose the change.

NutterzUK commented 8 years ago

Thanks @matteosilv. Just a quick one in case you are also using this yourself, I think having reader.read(classes); twice (once for return) is probably not intentional and may perhaps slow it down.

I have a quick question. I'm using the core.io reader and javax.ws.rs.Path - but i'm finding the plugin only picks up the classes if they have @Api on them. I was under the impression the core reader would see @Path and not need @Api also. I'm also needing to specify each resource in the "locations" part of the plugin. Is there any way to make this easier and perhaps just use the @Path annotation without the need for @Api? https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X says: Without having those two combined, no output will be generated, unless scanAllResources config option is not set, in which case also @Path annotatied classes with no @Api annotation will be scanned.

Is there a way for me to set this setting through this plugin? This was one of the reasons I switched to the swagger io reader thinking it would fix this.

Thanks - any help is really appreciated.

matteosilv commented 8 years ago

the double read is a mistyping due to cut and pasting the code :).

I think you should init the Reader through this constructor:

public Reader(Swagger swagger, ReaderConfig config)

and provide the scanAllResources true option to the config instance you provide

Let me know if it worked

NutterzUK commented 8 years ago

Thanks! I'll have a go at this as soon as i'm back at my dev PC.

NutterzUK commented 8 years ago

My apologies for the slow reply - I have been spending some time looking into this and some other things. It looks like in the MavenDocumentSource loadDocuments() method it does this, regardless of the scan all configuration: swagger = resolveApiReader().read(apiSource.getValidClasses(Api.class));

This apiSource.getValidClasses method searches for all methods with the @Api annotation, so I think this would need to change to get it to search automatically. For now, for my particular project I can add these @Api annotations in, but it may be something which can be improved upon - I may do so myself and create a pull request if I can get the time to look further into it.

NutterzUK commented 8 years ago

It seems the swagger core reader also overwrites the swager.info which means that the swagger info passed in to maven gets overwritten and ends up being null. At the moment, I have a custom reader which I based on the core.io one and I can find where it does this and stop it from doing it, but this may be an issue for others.

netmindz commented 6 years ago

Is there a fix for this yet? None of the examples here of swaggerApiReader are complete and having to add @ApiParam to every body parameter would be very dull