Starting to understand Multi-tenancy
Tags: mongodb, javascript, tutorial, programming
Published: 2021-05-31 01:12:27

If you already know or work with multi-tenancy, Pay It Forward (read through to understand). If you don’t know, maybe you are already working with it and just don’t know it yet (just like me in the near past).

**TL;DR**

The multi-tenancy architecture consists of working with applications that will have multiple users sharing the same database, however, having access only to the data that belongs to them.

It is widely adopted in software as a service (SaaS) applications, as many customers often use it. These same becoming the tenants of this application.

Sometimes some software uses architecture to attack deeper situations, as it was in our case.

**SCENARIO**
We are developing an application where our tenant will work with more than one user to access the platform. However, in the beginning, it was designed for just one login to control it. That is, our tenant would have more residents with him using the same rent.

Then, we decided to stop (we were already starting development on the front end), go back, and reshape our entire database from the beginning.

**HOW TO IMPLEMENT?**

Before we get there, let’s look at some ways in which we can apply the architecture in various models to what is being used in RBAF Manager.

- **One database for each customer**
When accessing the software, it is responsible for directing the application to the cluster responsible for that user’s collections.

- **One collection for each customer**
Each user would have a collection of their documents. Something that becomes unworkable for an application that is just starting for several reasons. One key is the cost of maintaining something at this level in the future with a very large user base.

- **One database for all tenants**
Preferred by many companies is that it is easy to implement at the beginning of development (it is understood that the model concept is easy), distributing tenants in only one bank becomes the most common path.

And that’s why we decided to work. Our admin user may own other users and these users need to be “tied” to the company they belong to.

**IMPLEMENTATION**

It was then decided that our tenant would be called Team since the platform is geared towards sports teams and to control access to the data of this tenant would require that each model of our system had its id.

- Our basic tenant:
{% gist https://gist.github.com/daniloab/1f41723fb405b240123efd57d9699481.js %}

- The other models followed the pattern below made for `Player`

{% gist https://gist.github.com/daniloab/399c89b56a25a1ca2be576337be71b72 %}

The id of the team is referenced in the model and this becomes its owner.

**HOW DO I KNOW THE USER IS LOGGED AND WHICH TENANT BELONGS TO?**

Using GraphQL we can work with only one endpoint for all requests. This way, when a call is placed on it, we check if the Authorization header is present:

`const { user } = await getUser(req.header.authorization);`

You can function called getUser passing the token created at login.

Passing through it, the token is decoded and we now have access to this user ID.

With the id we consult the User collection and from it, we can access the tenant that he is part of. In this case, the team he belongs to. The team was added at the time of creation, following the same model as the player collection.

{% gist https://gist.github.com/daniloab/10011b510f06fffedfd57ae2215ce0b1 %}

{%  gist https://gist.github.com/daniloab/1252bdc47af1fe9ed761b670dbee0ba8 %}

As soon as the user is returned, it is set in the context of our GraphQL API (line 7).

{%  gist https://gist.github.com/daniloab/82fd332ca8b728663fdb847aa33719ac %}

And just pass it as a parameter in the resolution of a query or mutation, to have access to only that user’s information.

An example is a query `me`, which is used as a form of authentication to find out if there are any users logged in and authorized to access our API data.

{%  gist https://gist.github.com/daniloab/fec19a5f6236e10fce7be03ef129b291 %}

**Pay It Forward**
GraphQL combined with MongoDB is a really powerful stack and starting to use it has allowed us to build some really cool stuff and it’s just the beginning.

With that, the idea of ​​this text is to share a little of what we are building / learning and to receive feedbacks whatever it may be: improvements, corrections, new implementations, etc.

This idea was fueled by the message of the movie: Pay It Forward. In it, Trevor, who is in the seventh grade tries to get a great message across the film about a theory that is based on:

- When you are helped by one person, you must make up for it by helping three other people. Thus creating a Chain of Good.

This is our current, sharing, learning, evolving with the community. Combined with one of our principles, [How to Learning in Public](https://dev.to/daniloab_/how-to-learn-in-public-9ng).