Should Feign interface has @PathVariable and @RequestParam annotations with stated names to work?

2.3k Views Asked by At

In fresh openfeign library (version 3.1.3) there is a check in PathVariableParameterProcessor, that verifies, that arguments with @PathVariable annotation should have name attribute filled. Similar check exists in RequestParamParameterProcessor.

In openfeign official documentation there is no sign of that rule, there are examples with both named and unnamed annotations

In one of the issues of spring-cloud-netflix library (that as I heard is an openfeign's predecessor) people also recommend just declare names of parameters.

In my project I had declared openfeign interfaces without explicitly specified parameter names (e.g. @PathVariable String someId), and it was working until now. Now I get exception coming from check stated above.

... org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.mycompany.client.MyClient': Unexpected exception during bean creation; nested exception is 
java.lang.IllegalStateException: PathVariable annotation was empty on param 0.
...
                    Caused by:
                    java.lang.IllegalStateException: PathVariable annotation was empty on param 0.
                        at feign.Util.checkState(Util.java:122)
                        at org.springframework.cloud.openfeign.annotation.PathVariableParameterProcessor.processArgument(PathVariableParameterProcessor.java:52)
                        at org.springframework.cloud.openfeign.support.SpringMvcContract.processAnnotationsOnParameter(SpringMvcContract.java:280)
                        at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:126)
                        at org.springframework.cloud.openfeign.support.SpringMvcContract.parseAndValidateMetadata(SpringMvcContract.java:193)
                        at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:65)
                        at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:151)
                        at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:49)
                        at feign.Feign$Builder.target(Feign.java:268)
                        at org.springframework.cloud.openfeign.DefaultTargeter.target(DefaultTargeter.java:30)
                        at org.springframework.cloud.openfeign.FeignClientFactoryBean.getTarget(FeignClientFactoryBean.java:451)
                        at org.springframework.cloud.openfeign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:402)
                        at org.springframework.cloud.openfeign.FeignClientsRegistrar.lambda$registerFeignClient$0(FeignClientsRegistrar.java:235)
                        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1249)
                        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191)
                        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
                        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
                        ... 130 more

Client interface api example

    @GetMapping("/{entityType}/{entityId}")
    List<Document> getDocs(
            @PathVariable String entityType,
            @PathVariable String entityId,
            @RequestParam(required = false) String ownerId,
            @RequestParam(required = false) String q);

Can somebody explain, is it really mandatory routine to write names yourself, or is there another way to automate it?

3

There are 3 best solutions below

0
WeGa On BEST ANSWER

I stumbled upon related question on SO and this answer kind of answers my question too.

To formulate answer to my post:

  • Yes, it is mandatory by default
  • Yes, there is a way to automate it by configuring compilation, to preserve original method argument names in .class files and let feign's StandardReflectionParameterNameDiscoverer resolve these names by reflection
0
Ergashev Abduvohid On

Yes, to write names of path variable is mandatory. There is no info about this in official documentation of Spring OpenFeign also. So, use with name of parameter. @PathVariable("someId") String someId

0
Łukasz Olszewski On

In order to use e.g. @PathVariable String someId) without an explicit name parameter just apply Spring Boot’s Gradle plugin or spring-boot-starter-parent to your project.

It'll add -parameters to the compilation section in your project build tool which is required for such an approach.

More details from the documentation:

To let the input be mapped to the operation method’s parameters, Java code that implements an endpoint should be compiled with -parameters, and Kotlin code that implements an endpoint should be compiled with -java-parameters. This will happen automatically if you use Spring Boot’s Gradle plugin or if you use Maven and spring-boot-starter-parent.