DEV Community

nk sk
nk sk

Posted on

Building a Complete CRUD REST Client in Spring Boot Using Feign

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>
Enter fullscreen mode Exit fullscreen mode

Enable Feign in your main application class:

@SpringBootApplication
@EnableFeignClients
public class FeignCrudApplication {
    public static void main(String[] args) {
        SpringApplication.run(FeignCrudApplication.class, args);
    }
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

Key points:

  • @RequestHeader handles headers like Authorization.
  • @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());
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Why Use Feign?

  • Simplified REST calls: No need to manually write RestTemplate or WebClient 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)