本記事では、Spring Cloud Feignを利用したマイクロサービス間での内部API呼び出しについて解説します。サービスディスカバリ機構と連携し、サービス名に基づいて他のサービスを呼び出す方法に焦点を当てます。
設定
1. 依存関係の追加 (pom.xml)
まず、pom.xmlファイルにSpring Cloud Feignのスターター依存関係を追加します。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. タイムアウト設定 (application.properties)
src/main/resources/application.propertiesファイルで、必要に応じてHTTPクライアントのタイムアウト設定を行います。これにより、リクエストが長時間ハングするのを防ぎます。
# Feignクライアントのデフォルト実行タイムアウト (ミリ秒)
feign.client.config.default.
# hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=120000 # Hystrixを使用する場合
ribbon.read-timeout=120000
ribbon.connect-timeout=120000
コード実装
1. サービス呼び出しインターフェースの定義
呼び出し対象のサービスAPIを定義するインターフェースを作成します。ここでは、@FeignClientアノテーションに、サービスレジストリに登録されているサービス名を指定します。例として、ここでは自身のサービス("demo"というサービス名で登録されていると仮定)を呼び出すインターフェースRemoteApiServiceを定義します。
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 外部サービスを呼び出すためのFeignクライアントインターフェース.
* "demo" はサービスレジストリに登録されているサービス名です.
*/
@FeignClient("demo")
public interface RemoteApiService {
/**
* GETリクエストでパラメータを送信してデータを取得します.
* @param queryParam クエリパラメータの値
* @return 応答文字列
*/
@GetMapping(value = "/api/v1/resource", produces = MediaType.TEXT_PLAIN_VALUE)
String fetchDataGet(@RequestParam("param") String queryParam);
/**
* POSTリクエストでフォーム形式のパラメータを送信します.
* @param formData パラメータの値
* @return 応答文字列
*/
@PostMapping(value = "/api/v1/resource", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
String submitForm(@RequestParam("data") String formData);
/**
* POSTリクエストでJSON形式のリクエストボディを送信します.
* @param payload JSON形式のリクエストボディ
* @return 応答文字列
*/
@PostMapping(value = "/api/v1/process", consumes = MediaType.APPLICATION_JSON_VALUE)
String processJsonData(@RequestBody String payload);
}
2. 呼び出しを実行するコントローラー
定義したFeignクライアントインターフェースを使用して、実際のAPI呼び出しを行うコントローラーを作成します。ここでは、RemoteApiServiceをインジェクトし、各エンドポイントから呼び出しを実行します。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Feignクライアントを使用した内部サービス呼び出しのテスト用コントローラー.
*/
@RestController
public class ServiceConsumerController {
private final RemoteApiService remoteApiService;
@Autowired
public ServiceConsumerController(RemoteApiService remoteApiService) {
this.remoteApiService = remoteApiService;
}
@GetMapping("/invoke-get")
public String triggerGetCall() {
return remoteApiService.fetchDataGet("test-query");
}
@GetMapping("/invoke-post-form")
public String triggerPostFormCall() {
return remoteApiService.submitForm("form-data-value");
}
@GetMapping("/invoke-post-json")
public String triggerPostBodyCall() {
String jsonData = "{\"message\": \"hello from client\"}";
return remoteApiService.processJsonData(jsonData);
}
}
3. Feignクライアントの有効化 (アプリケーションクラス)
アプリケーションのエントリポイントとなるクラスに@EnableFeignClientsアノテーションを追加し、FeignクライアントのスキャンとBeanの登録を有効にします。また、Eurekaなどのサービスディスカバリを利用している場合は、@EnableDiscoveryClient(または@EnableEurekaClient)も併せて指定します。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* Spring Boot アプリケーションのエントリーポイント.
* Feignクライアントとサービスディスカバリを有効にします.
*/
@SpringBootApplication
@EnableDiscoveryClient // または @EnableEurekaClient
@EnableFeignClients
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}