Openfeign
คือ library ใช้ในการเรียก Http request ด้วยการเขียนแบบ declarative โดยปกติแล้วเวลาเขียนโค้ด เรียกใช้งาน Http request เราจะต้องเขียนโค้ดเป็นลำดับขั้นตอนค่อนข้างเยอะแบบนี้
RestTemplate restTemplate = new RestTemplate();String url = "https://jsonplaceholder.typicode.com/posts/1";
ResponseEntity<PostDto> response = restTemplate.getForEntity(url, PostDto.class);
if (response.getStatusCode().is2xxSuccessful()) { PostDto post = response.getBody(); System.out.println(post.getTitle());} else { throw new RuntimeException("Request failed with status: " + response.getStatusCode());}
แต่ถ้าเราใช้ OpenFeign จะทำให้โค้ดกระชับขึ้น เพราะเราสามารถเขียนแบบ declarative ได้เลย เช่น
@FeignClient(name = "jsonPlaceholder", url = "https://jsonplaceholder.typicode.com")public interface PostClient {
@GetMapping("/posts/{id}") PostDto getPostById(@PathVariable("id") Long id);}
Declarative style คือการเขียนโค้ดในลักษณะที่ บอกความต้องการ โดยไม่ต้องกำหนดรายละเอียดการทำงานทีละขั้น ซึ่งในตัวอย่างนี้ กระบวนการที่เกิดขึ้นคือ
- method getPostById ให้เรียก HTTP GET
- ไปที่ path /posts/id
- แล้ว map ค่ากลับมาเป็น PostDto

จะเห็นได้ว่าเราไม่ต้องเขียนโค้ดเรียก HTTP client เองเลย ทำให้โค้ดสั้น กระชับ สะดวกสุดๆ
Ref link
Section titled “Ref link”- โค้ดสั้น กระชับ และเข้าใจง่าย
- สร้างการเชื่อมต่อกับ API ได้อย่างรวดเร็ว
- ยากต่อการจัดการเงื่อนไขซับซ้อน เช่น การแปลง request/response หรือการจัดการ exception แบบพิเศษ
- ความยืดหยุ่นต่ำกว่าการเขียนโค้ดแบบ imperative ตรง ๆ
เริ่มต้นการใช้งาน
Section titled “เริ่มต้นการใช้งาน”เพิ่ม dependency openfeign
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' // สำหรับกรณีทำเป็น library แยก เพื่อให้ OpenFeign แปลง JSON เป็น DTO ได้ implementation('com.fasterxml.jackson.core:jackson-databind')
สร้าง interface ขึ้นมา
@FeignClient(name = "oneId", url = "http://localhost:3000")public interface OneIdClient {
@GetMapping("/api/v1/users") SuccessResponse<PageResponse<UserDto>> getUsers();
}
อธิบายทีละขั้นตอน
- ใส่ @FeignClient เพื่อกำหนดให้ interface นี้เป็น Feign Client
- name ใช้ตั้งชื่อ client
- url ระบุ URL ของ API ปลายทาง
- กำหนด method โดยใช้ annotation เช่น @GetMapping เพื่อเรียก HTTP GET พร้อมระบุ path ของ endpoint
- OpenFeign จะจัดการ HTTP request และ mapping response เป็น
SuccessResponse<PageResponse<UserDto>>
ให้โดยอัตโนมัติ
PostMapping
Section titled “PostMapping”@PostMapping("/api/v1/users")SuccessResponse<UserDto> createUser(@RequestBody CreateUserRequest request);
GetMapping
Section titled “GetMapping”@GetMapping("/api/v1/users")SuccessResponse<PageResponse<UserDto>> getUsers( @RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "size", defaultValue = "10") int size);
PutMapping
Section titled “PutMapping”@PutMapping("/api/v1/users/{id}")SuccessResponse<UserDto> updateUser( @PathVariable("id") String id, @RequestBody UpdateUserRequest request);
DeleteMapping
Section titled “DeleteMapping”@DeleteMapping("/api/v1/users/{id}")SuccessResponse<Void> deleteUser(@PathVariable("id") String id);
QueryMapping
Section titled “QueryMapping”@Data@NoArgsConstructor@AllArgsConstructorpublic class GetAllUserParamsDto extends PageParams { private List<String> userIdIn; private String fullNameLike; private List<String> rolesIn; private List<Integer> groupIdsIn;
private SortOrder sortByFullName;
public enum SortOrder { ASC, DESC }}
@GetMapping("/internal/api/v1/users")SuccessResponse<PageResponse<UserDto>> getUsers(@SpringQueryMap GetAllUserParamsDto params);

ถ้าเราลองสังเกตุการออกแบบ api ของ openfeign จะมี annotaion หรือวิธีเขียนเหมือนกับ การสร้าง Rest controller เลย
อ่านค่า จาก application.yml
Section titled “อ่านค่า จาก application.yml”เวลาใช้ @FeignClient
เราสามารถ map ค่า name และ url ให้ไปอ่านจาก application.yml
กำหนดค่าใน application.yml
feign: name: store-service url: http://localhost:8081
ใช้ค่าใน @FeignClient
@FeignClient(name = "${feign.name}", url = "${feign.url}")public interface StoreClient { //..}

แบบนี้จะช่วยให้ไม่ต้อง hardcode ค่าในโค้ด เวลาเปลี่ยน environment (dev, uat, prod) ก็แค่เปลี่ยนใน application.yml ได้เลย