コードを生成する前のアーキテクチャ上の決定

Lino は大量のコードを迅速に生成しますが、結果の品質は生成前の決定に依存します。制限、プロジェクトの種類、コミュニケーション戦略、技術的負債の許容レベルを選択することで、初期の生産性が手戻りに変わることを防ぎます。

高度なサービス、モジュール、機能を作成する前に、このページをアーキテクチャ チェックリストとして使用して、チーム、ドメイン、運用を調整します。

プロジェクトの種類

走る前に lino project new、システムの目的を定義します。内部管理プロジェクト、マルチtenant SaaS、パブリック API、および分散プラットフォームには、さまざまなニーズがあります。

  • 簡単なアプリケーション: コンテキストが少なく、単一の導入であり、運用上の独立性の必要性が低い。
  • モジュラーモノリス: 同じプロセス内に複数のモジュールがあり、明確な境界があり、運用コストが低くなります。
  • マイクロサービス: 個別のサービス、独立した展開、非同期通信、および運用の複雑さの増大。
  • SaaS: tenantの分離、強力なセキュリティ、秘密、rate limiting、可観測性、および明確な請求/運用の決定が必要です。

この決定は、初日にどのような懸念事項が発生するかについても定義します。 SaaS はtenantを遅延詳細として扱うことはできません。パブリック API は、rate limitingと明確な契約がなければ誕生できません。イベントを使用するソリューションでは、Outbox、冪等性、可観測性について考える必要があります。複数のカルチャを含むアプリケーションでは、最初から散在する文字列を避ける必要があります。

基盤を作成するときは、サポートされるカルチャ、分散キャッシュ、非同期通信、コード アナライザー、データベース タイプ、Web アプリの存在、認証、tenantとワーカーなどの主な選択を記録します。これらのオプションは、パッケージ、テンプレート、AppHost、パラメータ、secrets、生成されたプロジェクト、および後でアーキテクチャを変更するために必要な作業に影響します。

モジュラー モノリス マイクロサービスとモジュラー モノリス マイクロサービスの比較

モジュラーモノリスにより、明確な内部規約を持つモジュールにドメインを編成できるため、ビルド、デバッグ、展開がよりシンプルになります。マイクロサービスは、独立した規模、別々のチーム、安定したビジネス境界、または異なる運用要件などの強力な理由がある場合にのみ効果を発揮します。

モジュラーモノリスから始めることは、アーキテクチャを無視することを意味するものではありません。これは、ドメインがまだ検出されている間は単純なデプロイメントを維持しますが、すべてがエンティティ、サービス、共有テーブルの単一の塊になるのを防ぐ内部制限を作成することを意味します。これが「シンプルに始める」ことと「構造を持たずに始める」の違いです。

基準モジュラーモノリスマイクロサービス
展開する最もシンプル、通常はユニークサービスごとに独立
一貫性ローカルトランザクションの維持が容易になるイベント、Outbox、および結果整合性が必要です
手術インフラストラクチャコストの削減可観測性、キュー、再試行、自動化の向上
リファクタリング最初は安い契約がすでに発行されている場合はさらに困難になります

Lino は両方のパスをサポートします。決定は、技術的な好みだけでなく、チームの領域と運用能力に従う必要があります。マイクロサービスには、デプロイメントの自動化、分散型可観測性、コントラクトのバージョン管理、ネットワークのフォールト トレランス、メッセージング、再処理、データ ガバナンスが必要です。チームがまだこれを安全に運用できない場合、配布が早すぎるとリスクが増大することがよくあります。

ドメインを学習し、製品を検証し、操作を制御可能に保つことが優先される場合は、モジュラー モノリスを使用します。運用の独立性がすでに具体的なニーズである場合、つまり、別個の規模、実際の所有権を持つチーム、独立したリリース サイクル、またはシステムの部分間で互換性のないインフラストラクチャ要件がある場合には、マイクロサービスを使用します。

サービスとモジュールの制限

適切な制限により結合が軽減され、各ルールの所有者が明確になります。テーブルごとまたは画面ごとにサービスを作成することは避けてください。サービスとモジュールはビジネス機能を表す必要があります。

  • Catalog: 営業担当者が参照した製品、カテゴリ、商業情報、およびデータ。
  • Sales: 注文、カート、適用された価格設定、スナップショット、商業フロー。
  • Stock: 空き状況、予約、移動。
  • Security: ユーザー、ロール、権限、認証、トークン。

適切な制限には、独自の言語、一緒に変更されるルール、明確な所有権の下にあるデータ、および他のコンテキストと通信するための明示的な契約があります。不正な制限は通常、「共通」モジュール、複数の領域で共有されるエンティティ、全員が参照するテーブル、または新しい画面があったために作成されたサービスとして表示されます。

モジュールが別のモジュールからのデータを必要とする場合は、API、統合イベント、シャドウ エンティティ、または境界の再形成のいずれかを選択します。別のモジュールのバンクへの直接アクセスは、構造的な結合の兆候です。 2 つのモジュールが同じプロセスで実行され、同じ物理データベースを使用する場合でも、スキーマ、永続化プロジェクト、および契約はビジネス境界を保護する必要があります。

  • 良好な限界標識: モジュールは、内部の詳細のために別のモジュールの再コンパイルを強制することなく、そのエンティティと移行を進化させることができます。
  • 弱い閾値信号: エンティティへの単純な変更では、そのエンティティを認識すべきではない画面、クエリ、およびモジュール ハンドラを確認する必要があります。
  • 隠れた依存関係の兆候: 消費者はテーブル、技術分野、または生産者の内部ルールについて「知りすぎる」必要があります。

意識的な技術的負債

技術的負債は単なる欠陥ではありません。将来のコストを承知で品質を先送りするという決断です。問題は、名前も所有者も返済計画もないまま借金を生み出すことです。

SaaS またはモジュラー システムでは、最も危険な技術的負債は単に長いメソッドではありません。進化を制限するのは負債です。個別に変更できないモジュール、信頼性の高い分離のないtenant データ、リポジトリ内の秘密、制限のない機密性の高いエンドポイント、再処理のないイベント、明確な契約のない統合などです。

  • 生成およびカスタマイズ中に作成されたドキュメントのショートカット。
  • 次世代ステージに進む前に、ビルドとテストを実行します。
  • ローカルハッキングを繰り返すことによって発生した問題を修正しないでください。パターンが間違っている場合は、パターンまたはテンプレートを調整します。

すべてのアーキテクチャ上の決定を監査可能なものとして扱います。メッセージングを有効にしないことを選択した場合、現在のフローは非同期処理に依存しないことに注意してください。tenantごとに列を選択する場合は、必ずフィルターとテストを行ってください。同期統合を選択する場合は、タイムアウト、非可用性、および契約エラーを設計の一部として想定します。

コミュニケーション戦略

一貫性、遅延、トレーサビリティ、結合に対する実際のニーズに応じて通信を選択してください。主な問題は、「どのテクノロジーを使用するか?」ではなく、「生産者は今すぐ答えを必要としています。消費者が操作をキャンセルできなかった場合、データの所有者は誰ですか?」です。

モジュラー システムで最も一般的なエラーは、通信を隠れた依存関係に変換することです。つまり、あるモジュールが別のモジュールのテーブルにクエリを実行したり、内部エンティティを再利用したり、外部リポジトリを挿入したり、失敗を処理せずに同期呼び出しを作成したりします。これは最初は生産的であるように見えますが、境界が明確でなくなるため、その後の変更はさらに危険になります。

  • 同期呼び出し: すぐに相談でき、依存も許容できる。長い滝は避けてください。
  • ドメインイベント: 同じ適用範囲内の内部反応。
  • 統合イベント: モジュール、サービス、またはシステム間の通信。通常は Outbox を使用します。
  • Shadow Entity: プロデューサーに直接依存せずに、相談と検証を行うための最小限のローカル コピー。
  • 外部 HTTP 統合: タイムアウト、再試行、ログ、障害処理を備えたサードパーティのサービスに適しています。

ルールを即時更新する必要がある場合は、同期ストリーミングを使用するか、しきい値を修正してください。最終的な整合性を受け入れる場合は、結合を減らすためにイベントを優先します。コンシューマーが別のコンテキストからデータの小さなサブセットを読み取る必要があるだけの場合は、元のエンティティ全体を公開するよりもシャドウ エンティティの方が安全である可能性があります。

質問推奨方向
ユースケースを完了するには応答が必要ですか?タイムアウト、予測可能なエラー、および明確なコントラクトを備えた明示的な同期統合。
消費者が離れている場合でも、生産者はトランザクションを確認する必要がありますか?Outbox と非同期処理との統合イベント。
消費者は最小限のデータを検証または参照するだけで済みますか?読み取りモデルのローカル所有権を持つ、イベントまたは統合によって強化されるシャドウ エンティティ。
変更は同じ集合コンテキスト内または限定されたコンテキスト内で発生しますか?不要な外部コントラクトを公開せずに、ドメイン イベントまたはドメイン ローカル ロジックを実行します。
処理されていないエラーが発生しました。 再読み込み 🗙