マイクロサービス間でDTOオブジェクトを共有する


15

TL; DR-サービス間でPOJOライブラリを共有しても大丈夫ですか?

一般的に、可能な場合は、サービス間の共有を厳密に制限します。データを共有しているサービスが、クライアントが使用するクライアントライブラリを提供するかどうかについては、いくつかの議論がありました。client-libは通常、サービスのクライアントが使用するオプションであり、client-libを使用するか、代替言語を使用してライブラリなどの一般的な側面を使用するかを問わず、APIを消費できます。

私の場合、データのオブジェクトを作成するサービスを検討しています。このオブジェクトがPETであると仮定しましょう。これはデータベースエンティティではなく、厳密に基になるデータを暗黙的に表すPOJOです。このPOJOは、APIが定義したものです。想定:ペット-年齢、体重、名前、所有者、住所、種など

サービス1 -PetKeeper:何らかの理由でペットを生成し、すべてのデータを保持し、このサービスを参照してペットを取得するか、ペットに変更を加え、名前の変更または住所の変更を行う必要がありますこのサービスへのAPI呼び出し。

サービス2 -PetAccessor:このサービスはペットを収集し、検証チェックを行います

サービス3,4-より多くの中間サービス呼び出し

サービス5-ユーザーインターフェイス

これらは非常にarbitrary意的ですが、ポイントは簡単です。UIまたはユーザー向けのサービスは、何らかの方法でこの「PET」オブジェクトを提示したいと考えています。APIを介してサービスを呼び出す必要があります。サービスは、サービスを呼び出し、サービスを呼び出すなど、必要な情報を収集してリレーバックを開始するサービスに到達するまで呼び出します。最後に、UIサービスには表示するPETオブジェクトがあります。

これは非常に一般的ですが、絶対的な考え方で、すべてのサービスでPETオブジェクトを複製しました。DRY(繰り返さないでください)の原則は、サービス内のコードにのみ適用され、サービス全体には適用されませんが、ポイントはまだあります。フィールドを追加したらどうなりますか...それぞれのPOJOの5つのサービスを変更する必要があります。

-または-APIからのpojoの一部を含むPet-Objects-Libraryを提供できます。各サービスはライブラリにインポート/依存できます。サービス自体への依存関係はありませんが、一般的なライブラリのみに依存しています。各サービスが同じタイプのオブジェクトを持ち、更新が簡単になるように、私はこのアイデアが好きです。しかし、私はGod-Objectsを心配しています。

賛否両論-最適な設計は何ですか?同じPOJOクラスの繰り返しを最小限に抑えながら分離されたままにするために、サービス間でデータを渡すために何をしましたか?



@DaiKaixian:確かに、OPがGodオブジェクトと一緒に行くこと提案しているわけではありませんよね?それは日常的にアンチパターンと考えられています。

@javaguyの答えに同意します。

そして、私は言いたいのですが、あなたはvisitor-patternを検討することができます。en.wikipedia.org/wiki/Visitor_pattern 。POJOですべてのフィールドとセッター/ゲッターを作成し、マイクロサービス間で共有します。異なるマイクロサービスでPOJOに対して何らかの操作を行いたい場合は、VisitorClassを記述します。

ありがとう。この「共通ライブラリ」を持つことをためらうのは、それが成長するということです。そしてそこには、サービス1と3だけ、または2と4、またはすべて、またはそれらの任意の組み合わせだけを対象とするオブジェクトがあります。訪問者パターンを使用するか、単純なDTO POJOを使用するかどうかにかかわらず、すべてのDTOを含む一般的なDTOライブラリパッケージのタイプ。これは、これらのオブジェクトをすべて含めることを許容しますが、可能な限りそれを維持しようとしますか?少なくともオブジェクトは、使用したい場合に必要な人に提供されます

回答:


5

最高のデザインは何ですか?

バックエンドサービス(一般的なビジネスロジックを処理する)で同じPet DTOオブジェクトを再利用できますが、プレゼンテーション層(ユーザーインターフェイス)に関しては、一般にFormBean(フィールドが追加された別のBean)を使用することをお勧めしますプレゼンテーションロジック)を使用して、プレゼンテーションロジックとビジネスロジックを明確に分離します。

これは、サービスが再利用可能である必要があり、単一のサービスが複数/異なるエンドポイント(フロントエンドまたは異なるWebサービスなど)によって公開/再利用される可能性があり、それらの各エンドポイントが追加されるフィールドを必要とする可能性があるためですサービスの上のそれぞれのコントローラーまたはレイヤー(アダプターなど)。

同じPOJOクラスの繰り返しを最小限に抑えながら分離されたままにするために、サービス間でデータを渡すために何をしましたか?

ビジネス層とWeb層の間で単一のBeanを使用する場合、プレゼンテーションロジックをビジネスロジック緊密に結合することになります。これは、フロントエンドの要件のサービスを変更することになります(たとえば、異なる日付形式ユーザーインターフェースに表示されます)。また、(FormBeanのか、その逆にDTOのような)豆間でデータをコピー/移入のこのプロセスを行うために、次のようなライブラリを使用することができるのApache BeanUtils.copyProperties()ドーザーを 定型的なコードを避けるために


プレゼンテーション層は、おそらく、必要に応じて異なる属性を持つプレゼンテーションBeanとして着信ペイロードをデシリアライズする必要があることに同意します。しかし、一般に、すべてのバックエンドサービスで同じDTOオブジェクトを再利用しても大丈夫ですか?通常、これらのDTOパッケージは、それらを必要とする少数のサービスについてのみ小さなパッケージに分離しようとします。私は、すべてのサービスが依存する75以上のマイクロサービス用のDTOを含むDTOライブラリパッケージのジャンクドロワーを持つのにうんざりしています。そもそもオプションであるのはDTOオブジェクトだけなので、それで問題ないのですか?

はい、PetServices重複を避けるために、同じDTOオブジェクトを明らかに同じようなバックエンドサービスで再利用できます。しかし、私のポイントは、バックエンドとフロントエンドを密に結合しないことです、それだけです。
開発者

4

DTOがすべてのマイクロサービスで同じビジネスエンティティを表す場合、サービス間で共有されるクラスは1つだけである必要があります。同じオブジェクトに対して重複したコードを持つことは(ほとんど)決して正しくありません。


3
マイクロサービス間でDTOを共有するのは悪夢です。「このバージョンにはすでにこのフィールドがありますか?たぶん?」しばらくすると、本当の混乱に陥ります。この場合、コードの複製が適切です。
Mejmo

1

私が今どのように計画するかは、各サービスがDTOのみをパッケージ化し、それらをjar libとしてNexusに配置することです。他のサービスがそれらを必要とする場合、manve / gradleの依存関係としてDTOライブラリを取得します。新しいDTOバージョンが1つのサービスでリリースされた場合、古いバージョンも同時にサポートされている限りは問題ありません。下位互換性、バージョン管理などを壊さないでください。これはバックエンド間です。また、循環依存を防ぐために、dtoパッケージからサービスを分離することをお勧めします

ここで、バックエンドからフロントエンド、およびその逆見てください。プレゼンテーション層としてのUIが異なるという以前のコメントには同意しません。そうではない!!! UIは、イベントを消費および生成するマイクロサービスの1つにすぎません。

バックエンドからフロントエンドへの方向 私がやることは、POJO(dtos)をTypescriptインターフェースに変換し、NPMにパッケージ化し、Nexusにもロードすることです。UI nodejsベースのプロジェクトは、それらを使用して使用します。これはUIへの方法サービスです。

フロントエンドからバックエンドの方向 UIからサービスレイヤーイベントの場合、Typescriptインターフェイスを変換してPOJO(dtos)に変換し、jarとしてパッケージ化し、バックエンドサービスで使用されるjarの形式でNexus(または一部のリポジトリ)にアップロードします。

これらのプロセスは、CIプロセス(Travis、Gitlab CIなど)によって簡単に処理されます。

このアプローチに対するコメントを歓迎します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.