ハニーストーン/コンテキストを使用したマルチテナント アプリケーションの構築

PHPz
リリース: 2024-08-12 15:11:25
オリジナル
737 人が閲覧しました

Laravel の新しいコンテキスト ライブラリと混同しないでください。このパッケージは、マルチコンテキスト、マルチテナント アプリケーションの構築に使用できます。ほとんどのマルチテナント ライブラリには基本的に単一の「テナント」コンテキストがあるため、複数のコンテキストが必要な場合は少し面倒になる可能性があります。この新しいパッケージはその問題を解決します。

例を見てみましょう?

プロジェクト例

このサンプル アプリケーションでは、チームに編成されたグローバル ユーザー ベースがあり、各チームには複数のプロジェクトがあります。これは、多くの Software as a Service アプリケーションでかなり一般的な構造です。

マルチテナント アプリケーションでは、各ユーザー ベースがテナント コンテキスト内に存在することは珍しいことではありませんが、このサンプル アプリケーションでは、ユーザーが複数のチームに参加できるようにしたいため、グローバル ユーザー ベースとなります。
グローバルユーザーベースとテナントユーザーベースの図

Building a multi-tenant application with honeystone/context

SaaS として、チームが請求対象エンティティ (つまりシート) となり、特定のチーム メンバーにチームを管理する権限が付与される可能性があります。ただし、この例ではこれらの実装の詳細には立ち入りませんが、追加のコンテキストが提供されることを願っています。

インストール

この投稿を簡潔にするために、Laravel プロジェクトの開始方法については説明しません。これについては、公式ドキュメントをはじめ、より優れたリソースがすでにたくさんあります。ユーザー、チーム、プロジェクトモデルを備えた Laravel プロジェクトがすでにあり、コンテキスト パッケージの実装を開始する準備ができていると仮定しましょう。

インストールは簡単なコンポーザーです:

リーリー

このライブラリには便利な関数 context() があり、Laravel 11 の時点では Laravel 独自の context 関数と衝突します。これは実際には問題ではありません。関数をインポートすることもできます:

リーリー

または、Laravel の依存関係注入コンテナーを使用します。この投稿では、関数をインポートし、それに応じて使用していることを前提とします。

モデル

チームモデルを構成することから始めましょう:

リーリー

チームには名前、メンバー、プロジェクトがあります。アプリケーション内では、チームのメンバーのみがチームまたはそのプロジェクトにアクセスできます。

それでは、プロジェクトを見てみましょう:

リーリー

プロジェクトには名前があり、チームに属します。

コンテキストの決定

誰かが私たちのアプリケーションにアクセスすると、その人がどのチームやプロジェクトで作業しているのかを判断する必要があります。物事を簡単にするために、ルート パラメーターを使用してこれを処理しましょう。また、認証されたユーザーのみがアプリケーションにアクセスできると仮定します。

チームでもプロジェクトのコンテキストでもない:app.mysaas.dev
チームコンテキストのみ:app.mysaas.dev/my-team
チームとプロジェクトのコンテキスト:app.mysaas.dev/my-team/my-project

ルートは次のようになります:

リーリー

これは、名前空間が衝突する可能性があるため、非常に柔軟性の低いアプローチですが、例は簡潔に保たれています。実際のアプリケーションでは、これを少し異なる方法で処理する必要があるでしょう。おそらく、anothersaas.dev/teams/my-team/projects/my-project または my-team.anothersas.dev/projects/my-project.

まず AppContextMiddleware を見てみましょう。このミドルウェアはチーム コンテキストを初期化し、設定されている場合はプロジェクト コンテキストを初期化します。

リーリー

まず、ルートからチーム ID を取得し、ルート パラメーターを忘れます。パラメーターがコンテキスト内に入ったら、コントローラーにパラメーターを渡す必要はありません。プロジェクト ID が設定されている場合は、それもプルします。次に、AppResolver を使用してチーム ID とプロジェクト ID (または null) を渡してコンテキストを初期化します。
リーリー

ここでもう少し続きます。


define() メソッドは、解決されるコンテキストを定義する役割を果たします。チームは必須であり、チーム モデルである必要があります。また、プロジェクトは受け入れられ (つまり、オプション)、プロジェクト モデル (または null) である必要があります。


resolveTeam() は初期化時に内部的に呼び出されます。チームまたは null を返します。 null 応答の場合は、ContextInitializer によって CouldNotResolveRequiredContextException がスローされます。


resolveProject() は初期化時に内部的に呼び出されます。プロジェクトまたは null を返します。この場合、プロジェクトは定義で必要とされていないため、null 応答でも例外は発生しません。


チームとプロジェクトを解決した後、ContextInitializer はオプションの checkTeam() メソッドと checkProject() メソッドを呼び出します。これらのメソッドは整合性チェックを実行します。 checkTeam() では、認証されたユーザーがチームのメンバーであることを確認し、checkProject() では、プロジェクトがチームに属していることを確認します。


Finally, every resolver needs a deserialization() method. This method is used to reinstate a serialised context. Most notably this happens when the context is used in a queued job.

Now that our application context is set, we should use it.

Accessing the context

As usual, we’ll keep it simple, if a little contrived. When viewing the team we want to see a list of projects. We could build our TeamController to handle this requirements like this:

projects; return view('team', compact('projects')); } }
ログイン後にコピー

Easy enough. The projects belonging to the current team context are passed to our view. Imagine we now need to query projects for a more specialised view. We could do this:

id) ->where('name', 'like', "%$query%") ->get(); return view('queried-projects', compact('projects')); } }
ログイン後にコピー

It’s getting a little fiddly now, and it’s far too easy to accidentally forget to ‘scope’ the query by team. We can solve this using the BelongsToContext trait on our Project model:

belongsTo(Team::class); } }
ログイン後にコピー

All project queries will now be scooped by the team context and the current Team model will be automatically injected into new Project models.

Let’s simplify that controller:

get(); return view('queried-projects', compact('projects')); } }
ログイン後にコピー

That’s all folks

From here onwards, you’re just building your application. The context is easily at hand, your queries are scoped and queued jobs will automagically have access to the same context from which they were dispatched.

Not all context related problems are solved though. You’ll probably want to create some validation macros to give your validation rules a little context, and don’t forget manual queries will not have the context automatically applied.

If you’re planning to use this package in your next project, we’d love to hear from you. Feedback and contribution is always welcome.

You can checkout the GitHub repository for additional documentation. If you find our package useful, please drop a star.

Until next time..


This article was originally posted to the Honeystone Blog. If you like our articles, consider checking our more of our content over there.

以上がハニーストーン/コンテキストを使用したマルチテナント アプリケーションの構築の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!