Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameter Annotations like @ApiParam do not traverse super classes for resolution #1575

Open
dilipkrish opened this issue Nov 21, 2016 · 18 comments

Comments

@dilipkrish
Copy link
Member

dilipkrish commented Nov 21, 2016

No description provided.

@yummish
Copy link

yummish commented Nov 30, 2016

I think I have a similar issue:

with the interface generated by swagger I have:

@Api(value = "lawyers", description = "the lawyers API")
public interface LawyersApi {

    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "kkj", response = StatsData.class) })
    @RequestMapping(value = "/lawyers/{lawyerId}/stats/case_compensation",
        produces = { "application/json" }, 
        method = RequestMethod.GET)
    StatsData getCaseCompensationStatsByLawyerId(
@ApiParam(value = "",required=true ) @PathVariable("lawyerId") String lawyerId
);
}

and controller:

@RestController
public class LawyersController implements LawyersApi {

  @Override
  public StatsData getCaseCompensationStatsByLawyerId( String lawyerId) {
    // TODO Auto-generated method stub
    System.out.println(lawyerId);
    return null;
  }
}

If i call this api, then the lawyerId is identified as query parameter, not the path variable as defined in the interface. To resolve this, I have to copy interface's parameters' annotations to the implementation.

So, I'm just wondering if I'm missing anything or is this relates to this issue.

thanks

@dilipkrish dilipkrish modified the milestones: Someday, 2.7.0 Feb 14, 2017
dilipkrish added a commit that referenced this issue Feb 14, 2017
Parameters annotations i.e. `@ApiParam` are not supported on interfaces because it can become a combinatorial problem when you nested/multi-interface subclassing controllers.

relates to #1575
@dilipkrish dilipkrish changed the title Parameter Annotations do not traverse super classes for resolution Parameter Annotations like @ApiParam do not traverse super classes for resolution Feb 14, 2017
@Morl99
Copy link

Morl99 commented Aug 31, 2017

@dilipkrish: I would like to +1 this, giving an explanation alongside.
Our ideal flow of using swagger is specification first. We currently specify an api.yaml document, generate interfaces, implement controllers (or change the existing controllers along the changes in the interfaces), and the running service then exposes the current specification through springfox.
We have a lot of parameter description, explaining how the parameters work, but this information cannot be exposed to service consumer at the moment.

If I can do something to help solving this issue let me know, but I think that I will probably not be able to fix this with a PR, as I am not familiar with the implementation details of the springfox project.

@swatisacheti
Copy link

Any timeline on when this will be fixed? Having the same issue as 388. The API doc still does not display descriptions of method parameters defined by @ApiParam in the interface. We're using version 2.7.0

@dilipkrish
Copy link
Member Author

@Morl99 would definitely appreciate help with fixing this. The only caveat to this issue is that you can run into a trap of traversing multiple interfaces as a result. If you can perhaps do that based on a configuration in the docket that would be awesome.

@codehustler
Copy link

The only caveat to this issue is that you can run into a trap of traversing multiple interfaces as a result

Everything else is picked up from my interface (e.g. @Api and @SwaggerDefinition on the interface, @ApiOperation over methods is working fine too, its just the @ApiParam over method parameters which is not working, so I am not sure why this is a problem with traversing multiple interfaces because it looks to me that the interfaces are already used.

@elieequa
Copy link

hello i have the problem of @apiparam on controller level?any idea?i'm using version 2.7.0.

@elieequa
Copy link

@dilipkrish

@dilipkrish
Copy link
Member Author

@elieequa ApiParam cannot be defined at the controller level

@elieequa
Copy link

@dilipkrish thank you for your reply,where should be used and how?can you show me an example maybee?thank you in advance

@Morl99
Copy link

Morl99 commented Sep 22, 2017

Sorry for going dark, we were on vacation.

I kind of agree with @Mulder8472 in that I do not understand why the ApiParams are special in comparison to ApiOperation. Can you roughly point me to a line of code where this extension needs to go. I am unfamiliar with the code base, but would be happy to give it a shot.

@dilipkrish
Copy link
Member Author

I kind of agree with @Mulder8472 in that I do not understand why the ApiParams are special in comparison to ApiOperation.

@Morl99 The reason they are different is because, spring caches using AnnotationUtils annotations on classes. And finding annotations is easy on those classes. However for @ApiParam, they are on parameters and spring doesnt cache or conveniently support looking up parameter annotations on the classes inheritance hierarchy. So it may cause performance problems.

Secondly, classes can have multiple inheritance for implementing interfaces. So traversing all the possible interfaces will be tricky in some cases.

I'll get back to you regarding guidelines how to implementation.

@luzzif
Copy link

luzzif commented Feb 13, 2018

I am currently facing the same annoying issue. I'd be glad to help, but as @Morl99 I'm not familiar in any way with the codebase, so... any news?

@soudmaijer
Copy link

+1

1 similar comment
@jharmelink
Copy link

+1

flowerrrr pushed a commit to flowerrrr/springfox that referenced this issue Mar 28, 2018
…asses for resolution springfox#1575.

Annotations of method parameters are now resolved by traversing super classes and interfaces.
Annotations are cached per handler method to avoid repeated lookups.
The code to find the inherited annotations is taken from swagger-core's ReflectionUtils class.
@wsalame
Copy link

wsalame commented Apr 3, 2018

A workaround is to copy paste the annotations from the generated interface into the controller.

Obviously, the problem is that annotations are not automatically updated if swagger def is modified

@luzzif
Copy link

luzzif commented Apr 4, 2018

I think we all knew about the workaround. The point of the issue is to prevent it by providing a proper solution.

@yoanthiebault
Copy link

As suggested by cramja in this comment, you might find the delegate pattern useful:

interface FooInterface {

  @ApiOperation("Gets Foo")
  @GetMapping("v1/foo/{id}")
  default Foo getFoo(@RequestParam @ApiParam String id) {
    return getFooImpl(id);
  }

  Foo getFooImpl(String id);
}

This pattern allows you to recover all the annotations without code duplication.

In my case this solution solved my issues and works well.

NB: if you use openapi generator, the delegatePattern option implement it. I think there is something equivalent with swagger codegen.

@AlexErmer
Copy link

Was there a fix? works for me using version 2.9.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests