HTTPサーバーとそのクライアントの間でインターフェースを共有する方法を見つけたとき、Spring Cloud Netflixのドキュメントを読んでいました。彼らはこの例をマイクロサービスに使用していますが、一般的なHTTP通信に拡張できない理由はありません:
// The shared interface, in a common library
public interface UserService {
@RequestMapping(method = GET, value = "/users/{id}")
User getUser(@PathVariable long id);
}
// The controller, on the server
@RestController
public class UserResource implements UserService {
}
// The same interface used for the client
@FeignClient("users")
public interface UserClient extends UserService {
}
これは、サーバー(Spring @RestController
がHTTPサーバーに変換する)とクライアント(Feign @FeignClient
がHTTPクライアント用にセットアップする)の両方として使用されるインターフェースを定義します。サーバークラスとクライアントクラスの実装は、別々のプロジェクトで使用できますが、同じインターフェイスを使用して、型が一致することを確認できます。
ただし、この例の下には次の警告があります。
注:通常、サーバーとクライアント間でインターフェースを共有することはお勧めできません。密結合を導入し、実際には現在の形式のSpring MVCでは機能しません(メソッドパラメーターマッピングは継承されません)。
さて、今はうまく統合されていません...しかし、その部分は、コードを共有し、サーバーとクライアント間のカップリングを導入することに対する警告の後にあります。このようにインターフェースを共有するのは、どうしてそんなに悪い考えだと思うのでしょうか?
それがないと、サーバーとクライアントがお互いに理解できるデータを送信することを保証することができなくなります。一方にフィールドを追加し、他方にはフィールドを追加せず、実行時までのみ不一致を検出できます。私の考えでは、カップリングを導入するのではなく、すでに存在するカップリングを明らかにするだけです。サーバーが受信するデータの種類を知らせる必要性よりも、サーバーを完全に独立させる必要性は大きいのでしょうか?