title: How to make GET requests to other Feign clients inside of a POST request?
body: <p>I have a REST API endpoint that makes use of several Feign clients to perform validation and processing. The endpoint in question accepts a POST request, but the Feign clients used for validation accept GET requests. When I make a POST request to my API endpoint I get the error below from the Feign clients that require a GET. I have my Feign clients methods annotated with <code>@GetMapping</code>, but it seems the request is still being sent as a POST. How do I make GET requests to Feign clients inside a POST request?</p>
  
  <pre><code>feign.FeignException: status 405 reading ValidationClient#checkData(String); content:
  {"timestamp":"2018-08-06T14:43:45.998+0000","status":405,"error":"Method Not Allowed","message":"Request method 'POST' not supported","path":"/"}
      at feign.FeignException.errorStatus(FeignException.java:62) ~[feign-core-9.5.1.jar:na]
      at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:91) ~[feign-core-9.5.1.jar:na]
      at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138) ~[feign-core-9.5.1.jar:na]
      at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) ~[feign-core-9.5.1.jar:na]
      at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-9.5.1.jar:na]
      at com.sun.proxy.$Proxy129.checkFormat(Unknown Source) ~[na:na]
      at com.example.datainput.DataInputController.acceptData(DataInputController.java:20) ~[classes/:na]
      at sun.reflect.GeneratedMethodAccessor126.invoke(Unknown Source) ~[na:na]
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:45005) ~[na:1.8.0_172]
      at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_172]
      at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:40002) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_172]
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_172]
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.32.jar:8.5.32]
      at java.lang.Thread.run(Thread.java:748) [na:1.8.0_172]
  </code></pre>
  
  <p><strong>Edit:</strong></p>
  
  <p>Feign Client</p>
  
  <pre><code>@FeignClient("validation")
  public interface ValidationClient {
  
      @GetMapping("/")
      boolean checkFormat(String data);
  
  }
  </code></pre>
  
  <p>The controller of the client</p>
  
  <pre><code>@RestController
  public class ValidationController {
  
      @Autowired
      ValidationProperties properties;
  
      @GetMapping("/")
      public boolean isValidFormat(@RequestParam String inputData) {
          return inputData.matches(properties.getValidFormat());
      }
  </code></pre>
  
  <p>}</p>
  
  <p>The REST endpoint that uses the client</p>
  
  <pre><code>@RestController
  public class DataInputController {
  
      @Autowired
      ValidationClient validationClient;
  
      @PostMapping("/")
      public String saveData(@RequestParam(name = "inputData") String inputData) {
  
          if (!validationClient.checkFormat(inputData)) {
              return "Invalid Format";
          }
  
          // save data here
  
          return "Input Success";
      }
  
  }
  </code></pre>
  
  <p>I am using version FINCHLEY.SR1</p>
  
  <p><strong>Edit 2:</strong></p>
  
  <p>I've noticed that my Feign clients in my controller seem to be misconfigured.
  They are of type <code>HardCodedTarget</code> and the url property just <code>http://&lt;service-name&gt;</code> (in this case <code>http://validation</code>), it doesnt actually point to the real service the client is supposed to be using. </p>
  
  <p><strong>Edit 3:</strong> 
  I added Ribbon</p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
      &lt;artifactId&gt;spring-cloud-starter-netflix-ribbon&lt;/artifactId&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>to my service applications and to my api that is using the Feign clients. Unfortunately I am still having the same issue. I have refreshed and rebuilt everything.</p>
  
  <p><strong>Edit 4:</strong> 
  I have created a GitHub project for this question. </p>
  
  <p><a href="https://github.com/zero01alpha/spring-cloud-demo" rel="nofollow noreferrer">https://github.com/zero01alpha/spring-cloud-demo</a></p>
  
  <p>the input-entry module uses the input-format and input-parse modules as Feign clients to validate the length and parse/print items of an input string. I have been using the alphabet as input so the minimum length for the input parameter is set to 26. input-format runs on port 8080, input-parse on 8081, and input-entry on 8082, all using the default path <code>/</code> as their only endpoint and requiring a request param named <code>input</code>. So to recreate the issue I'm having</p>
  
  <ol>
  <li>Start Config server</li>
  <li>Start Eureka Server</li>
  <li>Start input-format service</li>
  <li>Start input-parse service</li>
  <li>Start input-entry service</li>
  </ol>
  
  <p>Then, send a POST request to <code>localhost:8082</code> with a request param of <code>input</code> that is at least 26 characters. When I do this I get this response body.</p>
  
  <pre><code>{
      "timestamp": "2018-08-09T13:29:34.536+0000",
      "status": 500,
      "error": "Internal Server Error",
      "message": "status 405 reading InputFormatClient#checkFormat(String); content:\n{\"timestamp\":\"2018-08-09T13:29:34.504+0000\",\"status\":405,\"error\":\"Method Not Allowed\",\"message\":\"Request method 'POST' not supported\",\"path\":\"/\"}",
      "path": "/"
  }
  </code></pre>