If you’re working with microservices in Spring Boot, Feign is one of the easiest ways to communicate between services. It abstracts away the complexity of REST calls into simple Java interfaces. In this blog, we’ll build a CRUD Feign client that demonstrates headers, query parameters, path variables, and request body usage.
1. Setting Up the Project
First, add the necessary dependencies to your pom.xml
:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Enable Feign in your main application class:
@SpringBootApplication
@EnableFeignClients
public class FeignCrudApplication {
public static void main(String[] args) {
SpringApplication.run(FeignCrudApplication.class, args);
}
}
2. Defining the User DTO
We’ll use a simple User
entity for our CRUD operations:
public class User {
private Long id;
private String name;
private String email;
// getters and setters
}
3. Creating the Feign Client
Feign allows you to declare REST calls as Java interface methods. Here’s our complete UserClient:
@FeignClient(name = "userClient", url = "http://localhost:8080/api/users")
public interface UserClient {
// CREATE
@PostMapping(consumes = "application/json", produces = "application/json")
User createUser(@RequestHeader("Authorization") String token,
@RequestBody User user);
// READ by ID
@GetMapping(value = "/{id}", produces = "application/json")
User getUserById(@RequestHeader("Authorization") String token,
@PathVariable("id") Long id);
// READ all with query params
@GetMapping(produces = "application/json")
List<User> getUsers(@RequestHeader("Authorization") String token,
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size,
@RequestParam(value = "sort", required = false) String sort);
// UPDATE
@PutMapping(value = "/{id}", consumes = "application/json", produces = "application/json")
User updateUser(@RequestHeader("Authorization") String token,
@PathVariable("id") Long id,
@RequestBody User user);
// DELETE
@DeleteMapping("/{id}")
void deleteUser(@RequestHeader("Authorization") String token,
@PathVariable("id") Long id);
}
Key points:
-
@RequestHeader
handles headers likeAuthorization
. -
@PathVariable
maps URL path parameters. -
@RequestParam
handles query parameters for pagination or filtering. -
@RequestBody
sends JSON payloads for create/update operations.
4. Using the Feign Client in a Service
@Service
public class UserService {
private final UserClient userClient;
public UserService(UserClient userClient) {
this.userClient = userClient;
}
public void demo() {
String token = "Bearer your-jwt-token";
// CREATE
User newUser = new User();
newUser.setName("John Doe");
newUser.setEmail("john@example.com");
User createdUser = userClient.createUser(token, newUser);
// READ by ID
User user = userClient.getUserById(token, createdUser.getId());
// READ all
List<User> users = userClient.getUsers(token, 0, 10, "name,asc");
// UPDATE
user.setName("John Updated");
User updatedUser = userClient.updateUser(token, user.getId(), user);
// DELETE
userClient.deleteUser(token, user.getId());
}
}
5. Why Use Feign?
-
Simplified REST calls: No need to manually write
RestTemplate
orWebClient
code. - Declarative syntax: REST operations are just Java methods.
- Supports headers, query params, and request bodies seamlessly.
- Integrates well with Spring Cloud for load balancing and service discovery.
6. Bonus Tip: Global Headers
Instead of passing the Authorization
header every time, you can configure a Feign RequestInterceptor
to automatically attach it to all requests. This reduces boilerplate code.
Conclusion
Feign makes microservice communication clean and intuitive. With this setup, you now have a fully functional CRUD client that handles headers, query parameters, path variables, and request bodies. Perfect for any real-world Spring Boot application.
Top comments (0)