Tenant Providers
Every multitenanted application needs a way to retrieve instances of its tenants, regardless of where and how the tenant is stored. This is where the tenant provider comes in.
Introduction
One of Sprouts aims is to support all the different ways that people may build multitenanted applications, which cannot be achieved without a few abstractions. Tenant providers are one of these abstractions, as they abstract out the logic of retrieving instances of your tenant class, without understanding how they're stored.
Tenant providers are based on user providers, a feature of Laravel's native auth functionality that abstracts away the logic of retrieving authenticated users from their storage medium. In fact, the two types of classes are very, very similar.
How they work
Tenant providers are one of the simplest concepts within Sprout.
They exist to provide tenants, and each one knows how to deal with a particular storage medium.
They can provide tenants using a tenant identifier,
tenant key, or, a resource key if the tenant implements
TenantHasResources
.
Retrieving Tenants
All tenant providers implement the Sprout\Contracts\TenantProvider
interface, so will have three methods for
retrieving tenants, one for each type of value used to identify the tenant.
1public function retrieveByIdentifier(string $identifier): ?Tenant;2 3public function retrieveByKey(int|string $key): ?Tenant;4 5public function retrieveByResourceKey(string $resourceKey): (Tenant&TenantHasResources)|null;
The implementation of these methods will depend entirely on which storage medium the provider is for,
but there is some commonality between them.
In most cases, the methods will use their corresponding name method from the interface
(getTenantIdentifierName
, getTenantKeyName
and getTenantResourceKeyName
).
What the value returned by these methods means will again depend on what the provider is dealing with.
In cases where the provider is dealing with some form of persisted storage,
like a relational database or document store, it'll refer to a column or field within the table or document.
Boolean Logic
A core idea behind the tenant providers is that they must remain simple and operate using simple boolean logic. A tenant is either found or not, with no exceptions or extra conditions. Because of how Sprout is built, there are points between a tenant being retrieved and the tenant being set, where you can check any extra conditions you may have.
The only exception to this,
is the retrieveByResourceKey
method
which should throw a misconfigured exception
if the Tenant
implementation does not also implement the TenantHasResources
interface.
Provided Implementations
Sprout includes two implementations of the tenant provider, though there are plans for more in the future.
Eloquent
The Eloquent tenant provider is for applications whose tenants are Eloquent models. In most use cases, this will be the only tenant provider you need. You can read more about this tenant provider here.
Database
The database tenant provider is for applications that want to use Laravel's query builder without Eloquent.
It does require a class as a Tenant
implementation, but Sprout comes with a default one.
You can read more about this tenant provider here.
I need something else
While the provided implements should suffice for most people, there will be some that don't want to use Laravel's query builder or Eloquent. For these situations, you can create yourself a custom tenant provider.