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 {
}
これは、両方のサーバー(The Spring @RestController
は、それをHTTPサーバーに変換します)およびクライアント(Feign @FeignClient
は、HTTPクライアントで使用できるように設定します)。サーバークラスとクライアントクラスの実装は、別々のプロジェクトで使用できますが、同じインターフェースを使用して、型が確実に一致するようにします。
ただし、この例の下には、次の警告があります。
注:通常、サーバーとクライアントの間でインターフェースを共有することはお勧めできません。密結合が導入され、実際には現在の形式のSpring MVCでは機能しません(メソッドパラメーターマッピングは継承されません)。
OK、それで今はうまく統合されていません...しかし、その部分が来ますafterコードを共有し、サーバーとクライアントの間にカップリングを導入することに対する警告です。このようにインターフェースを共有するのは、なぜそんなに悪い考えだと彼らは思うのでしょうか?
これがないと、サーバーとクライアントがお互いに理解できるデータを相互に送信することを保証できなくなります。フィールドを一方に追加して他方に追加することはできず、実行時まで不一致のみを検出できます。私の考えでは、これは紹介結合ではなく、すでに存在する結合を明らかにするだけです。サーバーを完全に独立させる必要性は、サーバーが受け取るデータのタイプを知らせる必要性よりも大きいですか?
コメントに記載されている理由は、クライアントプラットフォームとサーバープラットフォームを緊密に結合することになるためです。ここで、サーバーの予期される契約を理解するために、クライアントはサーバーで使用している言語/プラットフォームを使用する必要があることを意味します。同じコード(特定の言語/プラットフォームの成果物)を共有することと特定の契約に同意することには違いがあることに注意してください。
代わりに、多くのプロジェクトでは契約にドキュメントを使用しています。標準プロトコル(RESTなど)を介したニュートラル形式(JSONなど)のリクエストとレスポンスの例。 (たとえば Stripe API docs を参照してください)。使用または許可する可能性のあるすべてのクライアントプラットフォームに対してコードベースのコントラクトを作成することは実際的ではないためです。さらに、API管理ツールを使用して ニュートラルコントラクト を定義する人もいます。
フィールドを追加する例は別の問題です-APIコントラクトのバージョン管理が重要である理由の例です。クライアントが設計されたバージョンを使用できるようにします。下位互換性のない新しいAPIバージョンが古いバージョンとともに存在します。古いバージョンのクライアントは、チームが更新を完了するまで、または古いバージョンを廃止するまで(非推奨/移行期間後)機能し続けます。 Parallel Change を参照してください。
警告の(暗黙のアドバイス)に従うと、クライアントとサーバーがそれぞれに意味のある方法とペースで進化するのに役立ちます。サーバーとクライアントが常に同じ言語/プラットフォームを共有し、同じペースで進化することを合理的に保証できる場合は、言語およびプラットフォーム固有のコードアーティファクトを契約として使用しても問題ないでしょう。ただし、これは特にNetflix OSSを対象とするプロジェクト(特に、必要なすべての複雑さを備えたクラウドのスケーラビリティとパフォーマンスを対象とするもの)の場合、妥当な期待ではありません。