In this tutorial, we will take a look at the and how to use it in a Spring Boot application. FeignClient is a library for creating REST API clients in a declarative way. So, instead of manually coding clients for remote API and maybe using Springs we declare a client definition and the rest is generated during runtime for use. FeignClient RestTemplate The Application We will build a small command line app, which simulates a full test for our previously created Kanban API. The sample app will create a new user, logs in, retrieves all boards and unregisters the user again. It captures the most common use case (POST, GET, DELETE + AuthN) Pre-requisites In this tutorial, we are going to use our Kanban API tutorial project. The RESTful API is showcased on , and we will use the running default implementation. Kanban backend I will cover the endpoints as far as they are related to this tutorial in the corresponding sections. For a full API doc, see . here The Kanban API was a tutorial I run on the Learnletter, and you can find all the pieces in the blog. Adding Dependencies We use Maven for this tutorial. As we do not want to mess with version numbers, the easiest way is to include the Spring Cloud setup in the in the Maven POM. dependencyManagement <dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Finchley.SR1</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement> Now, we can add the dependency to with a classical Spring Boot starter: Feign <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> FeignClient Basics The Feign client uses a declarative approach for accessing the API. To use it, we must first enable the Spring Cloud support for it on our Spring Boot Application with the annotation at the class level on a class. @EnableFeignClients @Configuration @SpringBootApplication@EnableFeignClientspublic class FeignIntroductionApplication implements ApplicationRunner{ //omitted} Next step is to declare an interface for accessing our API. We name it as it will provide the methods for calling our remote API. KanbanClient @FeignClient(name="KanbanClient",url= "https://kanbanbackend.herokuapp.com/")public interface KanbanClient { } To turn it into a Feign client, we must set the annotation on the interface and give it a name with the attribute and also set the remote URL with the attribute. SpEL is supported here so we could externalize the values to property files. Instead of the URL, we could also use service discovery using Eureka here. However, that is out of scope for this tutorial. @FeignClient name url To define a remote call, we must declare a method for that and use some annotations from Spring MVC, which are typically used on on the server side. They act the same, just on the client side now. @Controller So, let’s start with adding functionality. Making a POST call Adding the annotation on a method and passing a parameter in it, will turn the method into a POST call. In the annotation, we provide the endpoint relative to the URL we set on the annotation. @PostMapping @FeignClient @PostMapping(value = "/register") String registerUser(User user); is a simple POJO with a and field. Feign, and Spring will automatically transform it into JSON. User username password Making a GET call The same principle, but we use the on the method. We also send the authentication header. The API uses . @GetMapping X-Auth-Token @GetMapping("/boards")List<Board> listBoards(@RequestHeader("X-Auth-Token")String authHeader); The endpoint will return a list of all Kanban boards of the user. is the POJO for that and contains only and . /boards Board id name Making a PUT Call Same again, just with a annotation this time. @PutMapping @PutMapping("/board/{id}")Board changeBoard(@RequestHeader("X-Auth-Token") String authHeader,@PathVariable("id") Long id,Board board); We can change the name of a board by making a PUT to the endpoint of that board ( ). FOr the path variable see section below. /board/{id} Making Calls with Variables Making a DELETE Call Kind of boring, but it looks the same as the other, just with a annotation. @DeleteMapping @DeleteMapping("/unregister")ResponseEntity<Void> unregisterUser(@RequestHeader("X-Auth-Token") String authToken,Confirmation user); This endpoint requires a object with the user’s password to delete the account and will also just return a 200 if successful. Confirmation Making Calls with Variables If our endpoint requires a variable based on the entity like ids, we can use the annotation on a method parameter. It behaves the same as with Spring MVC @Controllers. @PathVariable The defined variable can then be used in the endpoint declaration on the like: @PutMapping( @PutMapping("/board/{id}")Board changeBoard(@RequestHeader("X-Auth-Token") String authHeader,@PathVariable("id") Long id,Board board); Call with Authentication We will use the endpoint for this. It requires the user credentials send as basic auth and will return a token for further authentication. login @PostMapping("/login")ResponseEntity<Void> loginUser(@RequestHeader("Authorization") String authHeader); The first way to pass additional information as header down is to add a method parameter with the annotation on it. The value of the parameter will be set as the value of the HTTP header defined in the annotation. @RequestHeader In the case of authentication, it is the header. As a value, we give it the Basic auth encoded string. Authorization In subsequent calls for the Kanban API, we will use the header with a token. X-Auth-Token Response headers can’t be returned directly as the method return value, but we can use Spring’s , which is a response wrapper. ResponseEntity When we call the endpoint successfully, it will return the auth token in a response header. The method will look like: /login @PostMapping("/login")ResponseEntity<Void> loginUser(@RequestHeader("Authorization") String authHeader); The as a parametrized type is needed as our endpoint does not return anything in the response body. Void We use Spring Session in the Kanban API, so the auth tokens are exchanged via the header. X-Auth-Token To retrieve the value we call: String token = response.getHeaders().getFirst("X-Auth-Token"); is of type . response ResponseEntity Authentication Alternative We can always pass down authentication headers using the annotation on each method. However, there is also an alternative way to specify that globally. @RequestHeader Like Spring MVC, Feign has an interceptor concept, which can be used to do specific stuff before a remote call. The entry point is the interface. RequestInterceptor With Spring we just need to provide a Bean implementing that particular interface to the Spring context, and it will be automatically picked up. Example: @BeanAuthInterceptor authFeign() {return new AuthInterceptor();} class AuthInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate template) {template.header("Authorization", "<your token>");}} Our interceptor is a Spring Bean, and thus we can use the power of Spring and externalize the authN info into properties or even retrieve it from a session scoped bean were we keep the information on a per-user basis. Using the FeignClient Now, we can inject the into our code like any other Spring Bean. On startup, Spring Cloud will set up the Feign client for us and give us a regular Spring Proxy so we can simply start working with the remote end. KanbanClient Our Final Client Our client using Feign looks like that in the end: @FeignClient(name="KanbanClient",url= "https://kanbanbackend.herokuapp.com/")public interface KanbanClient { @PostMapping(value = "/register")String registerUser(User user); @DeleteMapping("/unregister")ResponseEntity<Void> unregisterUser(@RequestHeader("X-Auth-Token") String authToken,Confirmation user); @PostMapping("/login")ResponseEntity<Void> loginUser(@RequestHeader("Authorization") String authHeader); @GetMapping("/boards")List<Board> listBoards(@RequestHeader("X-Auth-Token") String authHeader); @PostMapping("/boards")Board createBoard(@RequestHeader("X-Auth-Token") String authHeader,Board board); @PutMapping("/board/{id}")Board changeBoard(@RequestHeader("X-Auth-Token") String authHeader,@PathVariable("id") Long id,Board board);} The Sample App The is on GitHub. full working sample It will register a new user, log in, creates a board, change the board’s name, lists all boards and then unregisters the user at the end. Originally published at codeboje.de .