Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Cloud Feign Client @RequestParam with List parameter creates a wrong request

I have a Spring Clound Feign Client mapping defined as following

@RequestMapping(method = RequestMethod.GET, value = "/search/findByIdIn")
Resources<MyClass> get(@RequestParam("ids") List<Long> ids);

when I call

feignClient.get(Arrays.asList(1L,2L,3L))

according to what I can see in the debugger, the feign-core library forms the following request:

/search/findByIdIn?ids=1&ids=2&ids=3

instead of expected

/search/findByIdIn?ids=1,2,3

which would be correct for the server Spring Data REST endpoint declared in the same way as my Feign client method.

Thus, because of this issue, the request always returns empty set.

I have seen similar question, but it looks like the Feign client was working as I expect back in 2015.

I am using:

  • spring-cloud-starter-feign version 1.2.4.RELEASE
  • feign-httpclient version 9.4.0
  • feign-core version 9.4.0

Is there a way to correct the behaviour and "marry" the Spring Cloud Feign Client with the Spring Data REST defined endpoints?

like image 495
Sergey Shcherbakov Avatar asked Jan 19 '17 14:01

Sergey Shcherbakov


People also ask

How do you pass query parameters in feign client?

Query parameters can be configured in Feign clients by using the @RequestParam annotation from the Spring web framework on method arguments which should be passed as query parameters when calling the remote service.

Does feign client do load balancing?

Feign is a Java HTTP client that is implemented in Java to simplify RESTful API calls. Use @EnableFeignClients and @FeignClient to initiate a load balancing request.

How do you communicate between Microservices using Feign client?

Let's implement the Feign in our project and invoke other microservices using Feign. Step 1: Select currency-conversion-service project. Step 2: Open the pom. xml and add the Feign dependency.

Is feign client blocking?

Reactive Feign is great choice for the implementation of non-blocking API clients. It is a reactive version of OpenFeign which supports the creation of API clients without the need to writing implementation code. By just defining interface and configuration, development of API clients can be done effortlessly.


4 Answers

Thanks @prola for your answer.

Just to add an explicit example, @CollectionFormat(feign.CollectionFormat.CSV) annotation targets a method; you can't apply globally to your Feign Client interface.

So each method will be similar to:

@RequestMapping(value = ["/objects"], method = [RequestMethod.GET])
@CollectionFormat(feign.CollectionFormat.CSV)
fun findById(
    @RequestParam(value = "object.id", required = true) id: String,
    @RequestParam(value = "object.fields", required = false) objectFields: List<String> = DEFAULT_FIELDS_LIST,
    @RequestParam(value = "format") format: String = FORMAT,
): ResponseEntity<ObjectsDTO>

The result will be

/objects?object.fields=size,weight,location 

instead of

/objects?object.fields=size&object.fields=weight&object.fields=location 

You can also refer to:

  • 1.16.Feign CollectionFormat support
  • OpenFeign #542: Support Multiple Collection Formats
like image 157
albertocavalcante Avatar answered Oct 26 '22 20:10

albertocavalcante


In Feign you can annotate your controller with the following

@CollectionFormat(feign.CollectionFormat.CSV) and it will process collections in

the CSV format findByIdIn?ids=1&ids=2&ids=3

like image 35
prola Avatar answered Oct 26 '22 20:10

prola


I've just battled with this today, and the solution for me was surprisingly simple.

If you use brackets [] for denoting query array:

Resources<MyClass> get(@RequestParam("ids[]") List<Long> ids);

it will create a request that looks like this

/search/findByIdIn?ids[]=1&ids[]=2&ids[]=3

Most server side frameworks will interpret this as an array. If your server is also in spring then you can pick this up like this

@GetMapping("/search/findByIdIn")
public ResponseEntity findByIdIn(@RequestParam("ids[]") List<Long> ids) { ... }

Just keep in mind that the query has to be encoded, [] gets encoded to %5B%5D.

like image 27
Tomislav Civcija Avatar answered Oct 26 '22 19:10

Tomislav Civcija


I had the same issue with multiple occurence of the parametre instead of the expected comma separated sequence of items. The solution was really simple:

In my feign client I used arrays

feignClient.get(new Long[]{1L,2L,3L})

instead of collection/list:

feignClient.get(Arrays.asList(1L,2L,3L))

like image 38
JBelu Avatar answered Oct 26 '22 19:10

JBelu