Search code examples
javaspring-bootspring-mvcmicroservicesfeign

Feign Client GET request, throws "Method Not Allowed: Request method 'POST' not supported" from microservice


I have a Vue.js app with a spring backend, which makes calls via a Feign Client to an 'orders' microservice. I have many GET requests that are working fine using @PathVariable(s), but I have 1 GET request which can have any number of different URL params passed into it, and have defined an OrderListItemParameters class and have added it to the GET request, to pass the params to the microservice. I can see that the request is making it to the microservice, but it is getting denied with a "org.zalando.problem.spring.common.AdviceTrait : Method Not Allowed: Request method 'POST' not supported" error.

Ive made sure the OrderListItemParameters being sent by the feign client matches the OrderListItemParameters expected at the microservice. And there is no mention of POST in either the Feign client, or the microservice. I only have GET, and PUT endpoints.

Java BackEnd for FrontEnd Code:

@RestController
@RequestMapping("/api")
public class OrdersResource {

    ## THIS WORKS NO PROBLEM
    @GetMapping("/order/{orderId}")
    public @ResponseBody
    ResponseEntity<?> order(@PathVariable int orderId) throws Exception {
        return ResponseEntity.ok(orderClient.order(orderId));
    }


    ## THIS ENDPOINT IS THE ONE THAT FAILS
    @GetMapping("/order/list")
    public @ResponseBody
    ResponseEntity<?> orders(OrderListItemParameters orderListItemParams) {
        return ResponseEntity
           .ok(orderClient.getOrderList(orderListItemParams));
    }
}

@Component
@AuthorizedUserFeignClient(name = "orders")
public interface OrderClient {

    ## THIS WORKS NO PROBLEM
    @RequestMapping(method = RequestMethod.GET, value = "/api/order/pg/{orderId}")
    String order(@PathVariable("orderId") int orderId);

    ## THIS ENDPOINT IS THE ONE THAT FAILS
    @RequestMapping(method = RequestMethod.GET, value = "/api/order/list")
    String getOrderList(OrderListItemParameters orderListItemParams);
}

OrderListItemParameters Class passed in as URL params: (this is identical in the microservice)

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class OrderListItemParameters implements Serializable {

  private String searchPhrase;
  private String startDate;
  private String endDate;
  private ArrayList<String> sortKey;
  private ArrayList<String> sortValue;
  private Integer from;
  private Integer size;
}

(with getters, and setters) 

Microservice Controller:

@Controller
@RequestMapping("/api")
public class OrderController {

  ## THIS WORKS NO PROBLEM
  @GetMapping("/order/pg/{orderId}")
  public @ResponseBody
  Order pgorder(@PathVariable int orderId) {
    return orderService.getPgOrderById(orderId);
  }

  ## THIS ENDPOINT IS THE ONE THAT FAILS
  @GetMapping("/order/list")
  public @ResponseBody
  ResponseEntity getOrderListItemsByMerchant(OrderListItemParameters orderListItemParams) {
    return orderService
        .getOrderListItemsByMerchant(orderListItemParams);
}

Here's a pic of the logs: Clearly Stating GET requests... Logs

Any help figuring out why the controller thinks this is a POST request would be awesome.


Solution

  • Here's the solution that ended up working...

    #Resource
    @GetMapping("/order/list")
    public @ResponseBody 
    ResponseEntity<?> getOrderListItemsByMerchant(
        @RequestParam Map<String, Object> params) {
        // method code
    }
    
    #Feign Client
    @RequestMapping(method = RequestMethod.GET, value = "/api/order/list")
    ResponseEntity<String> getOrderList(@RequestParam Map<String, Object> params);
    
    #Microservice Controller
    @GetMapping("/order/list")
    public @ResponseBody
    ResponseEntity getOrderListItemsByMerchant(OrderListItemParameters orderListItemParams) {
        // method code
    }
    

    This allows me to fetch a URL with dynamic params, and the microservice still sees the request as a GET.

    It would be nice to have the same defined object on either side of the request, but I was unable to make @SpringQueryMap or @QueryMap work at all.

    I hate Feign.