web-dev-qa-db-ja.com

Web用のマルチテナントシングルページアプリケーションの設計

マルチテナントアプリケーションの設計を検討しています(まあ、それはマルチテナントだと思います)。単一ページアプリケーション、API、および共通データベースがあります。

ユーザーのグループがあり、それぞれに若干異なる要件があります。現時点では、ユーザーは複数のグループに所属することはできません

主な機能私たちが持っているもの:

  • 検索:ユーザーのグループごとに異なる検索フィールド
  • グリッド:ユーザーグループごとに異なる列
  • 詳細パネル:結果に表示するさまざまなフィールド

上記の各主要機能にはいくつかの共通のプロパティがありますが、一部は各グループに完全に固有です。

ここで2つの主な考慮事項があります。

  1. ユーザーグループごとのUIビューの処理
  2. 必要なプロパティのみを持つオブジェクトをフロントエンドにポストして提供します。

TypeScript + Angular 1をフロントエンドに、.NET Web APIをバックエンドに使用しています。

避けたい:

  • ワイヤーを行き来するすべてのグループのすべてのプロパティを含む神オブジェクト。
  • ユーザーグループに基づいて表示および非表示にするために、フロントエンドコードに多数のifステートメントが散らばっています。

これを念頭に置いて、私が検討している現在の設計は次のとおりです。

  • フロントエンドアプリケーションの読み込み時に、グループごとに異なるビューを読み込みます。
  • ビューに応じて異なるコントローラーをバインドする
  • 現在、これは、すべてのグループのJSのバンドルがクライアントに提供されることを意味します
  • これは、特定のリクエストオブジェクトを取り込んで特定のオブジェクトを返す、同じ操作の特定のエンドポイントを持つことができることを意味します。
  • フォルダー構造の観点から、コード機能で分離し、異なる場合はグループ化します。

これの利点は次のとおりです。

  • グループ固有のコードは、それが異なる場合に簡単に推論できます
  • ユーザーに関連するもののみを投稿および受信する。
  • ユーザーが複数のグループに属している場合は、ユーザーが所属するアクティブグループを変更することで、ミニアプリケーションを切り替える機能を提供できます。

これの欠点は次のとおりです。

  • ログインしたユーザーが所属するグループに応じて、ビューとコントローラーの読み込みに多くの手間がかかります。
  • すべてのグループのすべてのフロントエンドアプリケーションコードを事前に提供する
  • ユーザーが複数のグループに属している場合のグループのディープリンク/ルーティングの処理。これはquerystring paramで処理できると思います。 :(

考え?

2017年7月27日更新

したがって、作り上げの例を使用します。

検索基準は、グループごとにフィールドが異なることによって異なります。

  • Group a: Name, Age, DOB, Car type, Car engine size
  • Group b: Name, Age, Shoe size, shirt size, favourite colour

これを外挿すると、8つのグループがあり、それぞれに10の共通プロパティと5つのグループ固有のプロパティがあります。私の難問は次のとおりです。

すべてのグループのすべてのプロパティをカプセル化するリクエストオブジェクトを持つ単一の検索エンドポイントを使用する場合。これは50個のプロパティです(10個の共通+ 5 * 8グループ固有のプロパティ)。

特定のグループでは、15のみが関連します。適切な15のコードのみを使用し、他の35を除外するようにサーバー側のコードを作成する必要があります。

さらに、同じことが応答でも発生します。私は大きなオブジェクトを受け取りますが、その小さなサブセットのみがそのグループのユーザーに関連するデータを含み、残りはnullです。フロントエンド側でこれらの表示と非表示を処理するには、かなりの量の条件付きステートメントを配置する必要があります。

これはおそらくマルチテナントとは見なされていませんが、この種の問題に適した設計についてアドバイスを求めています。

3
Prabu

ユーザーベースで詳細が不足していますが、マルチテナント要件がないようです。また、あなたの見解がお互いにどのように異なるかについての詳細もほとんどありません。本能的には、あなたはマルチテナントではなく、実際には複数のグループを持っていると思います。また、あなたは後で自分に腹を立てるような解決策に傾いていると思います。より具体的には、検索ビュー、グリッドビュー、詳細ビューのそれぞれの個別の実装。

Keystone、keycloak、または別のサードパーティによる標準ユーザー認証を使用する必要があると思います。ユーザー/グループ/ロールを利用して、権限の階層を割り当てます。 USER_BASIC_PERMのようなものは、オブジェクトのID、名前、およびカテゴリへのアクセスを許可します。 USER_CASH_PERMは、コスト、価値、利益率へのアクセスを許可します。 USER_ADMIN_PERMを使用すると、サードパーティの購入者、URLからPOなどに関連するフィールドを表示できます。グループを使用すると、複数のロールの権限をまとめて、単一のグループでユーザーをより簡単に管理できます。

次に、ユーザーの権限に基づいてサブビューを含めたり除外したりして、3つのビューを作成できます。検索を送信するときは、サーバー側の役割に基づいてフィールドを検証する必要があります。詳細を返す場合は、クライアントに返す前に、許可フィルターを通過させる必要があります。長期的には、これは、テナントごとに個別のビューを実装するよりも維持が容易になります。

違いはユーザーの権限だけだと考えると、主要な機能は自己完結型であることがわかると思います。 「検索」は1つのサーバー側モジュールになります。グリッドデータアクセスは別のものです。サーバー側で同様の機能を維持すると、繰り返しが少なくなります。グループごとにサーバー側を分離するということは、すべての「グリッド」クエリにまたがる1つのバグを修正するために、3つの別々のモジュールにアクセスする必要があることを意味します。

長期的に考えてください。知っている3つのテナントに非常に近い5つのテナントを追加すると、後で実装するのに苦痛が少なくなります。

4番目のビューを追加するとします。権限チェックで一度追加しますか、それとも現在8つのテナントごとに一度追加しますか?

1
Kieveli