15

Here is my interface:

public interface SCIMServiceStub {
    @RequestLine("GET /Users/{id}")
    SCIMUser getUser(@Param("id") String id);

    @RequestLine("GET /Groups?filter=displayName+Eq+{roleName}")
    SCIMGroup isValidRole(@Param("roleName") String roleName);
}

Here getUser call works fine.

But isValidRole is not working properly as the request is eventually sent like this.

/Groups?filter=displayName+Eq+{roleName}

Here {roleName} is not resolved.

What am I missing here? Appreciate some help, as I'm clueless at this point.

Edit: One more question: Is there a way to avoid automatic url encoding of query parameters?

ℛɑƒæĿᴿᴹᴿ
  • 4,983
  • 4
  • 38
  • 58
Bee
  • 12,251
  • 11
  • 46
  • 73

5 Answers5

27

As the recent(2019.04) open feign issue and spring doc say:

The OpenFeign @QueryMap annotation provides support for POJOs to be used as GET parameter maps.

Spring Cloud OpenFeign provides an equivalent @SpringQueryMap annotation, which is used to annotate a POJO or Map parameter as a query parameter map since 2.1.0.

You can use it like this:

    @GetMapping("user")
    String getUser(@SpringQueryMap User user);
public class User {
    private String name;
    private int age;
    ...
}
Community
  • 1
  • 1
Frank.Chang
  • 883
  • 1
  • 10
  • 10
  • 2
    If I added `@JsonProperty("na-me")` on top of the `User#name` is it expected that feign should make a request with encoded "na-me" param rather than "name" ? cause I thought is should but it doesn't and I am not sure if I should ask a separete question about it or it is just how feign works – Filip Kowalski May 05 '21 at 18:15
  • @FilipKowalski Did you find the solution to your problem? – PraBhu May 13 '22 at 04:21
  • @FilipKowalski - could solve the issue with @JsonProperty("na-me") in this situation? – Andrew Niken Aug 24 '23 at 13:45
12

It seems to be caused by a bug that is already opened - https://github.com/OpenFeign/feign/issues/424

Like in comments, you can define your own Param.Expander something like below as a workaround.

@RequestLine("GET /Groups?filter={roleName}")
String isValidRole(@Param(value = "roleName", expander = PrefixExpander.class) String roleName);

static final class PrefixExpander implements Param.Expander {
    @Override
    public String expand(Object value) {
        return "displayName+Eq+" + value;
    }
}
yongsung.yoon
  • 5,489
  • 28
  • 32
12

Working fine using @QueryMap

URL: /api/v1/task/search?status=PENDING&size=20&page=0

Map<String, String> parameters = new LinkedHashMap<>()
        parameters.put("status", "PENDING")
        parameters.put("size", "20")
        parameters.put("page", "0")
        def tasks = restClientFactory.taskApiClient.searchTasks(parameters)

Inside Client Interface

@RequestLine("GET /api/v1/task/search?{parameters}")
List<Task> searchTasks(@QueryMap Map<String, String> parameters)
Chinthaka Dinadasa
  • 3,332
  • 2
  • 28
  • 33
  • 2
    I really like this approach. `@QueryMap` didn't worked for me instead replacing it with `@SpringQueryMap` does the job. Spring has some limitation while using `@QueryMap` for further reading: https://cloud.spring.io/spring-cloud-openfeign/reference/html/#feign-querymap-support – Dipen Feb 24 '21 at 00:55
2

With Spring feign client below works fine:

@GetMapping("/Groups?filter=displayName+Eq+{roleName}")
SCIMGroup isValidRole(@PathVariable(value = "roleName") String roleName);
Paulo Merson
  • 13,270
  • 8
  • 79
  • 72
hitesh
  • 176
  • 1
  • 3
1

Well, as suggested by @Frank.Chang you can use @SpringQueryMap for this:

@GetMapping("user")
String getUser(@SpringQueryMap User user);
public class User {
    @JsonProperty("na-me")  // json property won't work
    private String name;
    private int age;
    ...
}

But remember, in this case @JsonProperty("na-me"), won't work for you. For that you will have to create a getter for the field and add @Param annotation from feign package on the getter. like this.

public class User {
    private String name;
    private int age;
    ...
    @Param("na-me")
    public String getName() {
        return this.name;
    }

}
Rahul Soni
  • 31
  • 2