I'm looking at designing a multi-tenant application (well I believe it is multi-tenant). We have a single page application, an API and common database.
We have groups of users, each with their own slightly different requirements. A user cannot be in more than one group at the moment.
The key features we have are:
- Searching: Search fields varying per group of users
- Grid: Columns varying per group of users
- Details panel: Varying fields to show for the result
There are some common properties in each key feature above, but some are completely unique to each group.
I have two main considerations here:
- Handling the UI views per user group
- Posting and serving back to the front-end an object with only the properties required.
We are using TypeScript + Angular 1 for the front end, and .NET Web API for the backend.
I want to avoid:
- God objects that contain all the properties for all groups going back and forth over the wire.
- Lots of if statements littered in the front-end code to show and hide based on the user group.
With this in mind, the current design I am considering is as follows:
- Load different views per group at load-time of the front-end application
- Bind different controllers depending on the view
- Currently, this means the bundle of JS for all groups will be served to the client
- This means we can have specific endpoints for the same operation, taking in specific request objects and returning specific objects.
- From a folder structure perspective, separate by code feature, then group if it differs.
The advantages of this are:
- Code specific to a group is easy to reason when it differs
- Posting and receiving only what is relevant to the user.
- If a user belongs to multiple groups, we can provide them a functionality to switch between the mini-applications by changing the active group they are in.
The disadvantages of this are:
- A lot more plumbing on loading the views and controllers dependant on the group the logged in user falls into.
- Serving all the front-end application code for all groups up front
- Handling deep linking/routing for a group when a user belongs to multiple groups. I suppose this can be handled via querystring param. :(
So using a made-up example:
The search criteria varies by having different fields per group.
Group a: Name, Age, DOB, Car type, Car engine size
Group b: Name, Age, Shoe size, shirt size, favourite colour
Extrapolating this, we have 8 groups, each having 10 common properties and 5 group specific properties. My conundrum is as follows:
If I go with a single search endpoint with a request object encapsulating all the properties for all groups. That's 50 properties (10 common + 5*8 group specific properties).
For any given group only 15 are relevant. I need to make the server-side code to use only the 15 appropriate ones and exclude the other 35.
Further more, the same occurs on the response. I will receive a large object, of which only a small subset contains data pertinent to the user in that group, the rest being null. I will have to place a fair amount of conditional statements to handle showing and hiding these things on the front-end side.
This is probably not considered multi-tenant, but I'm trying seek advice on a good design for this type of problem.