#Multi-tenant database with Mongoose and Microservices

5 messages · Page 1 of 1 (latest)

prime sierra
#

Hi guys. I'm developing a multi-tenant - microservices system. By using mongoose and check the 'x-tenant-id' in every request headers, I can detech which tenant is using which database and ensure they will not be able to access each other database.

1 issue that I was facing is that, the checking step needs to be in Scope.REQUEST in order to check the header. However, it caused the "too many open connection" issue to MongoDB because each time I request to an API, it will open new connection.

1 solution that I found from Nest.js is Durable Provider https://docs.nestjs.com/fundamentals/injection-scopes#durable-providers. It actually worked because it performed some kind of caching the tenantId into a sub-map, so we don't have to query new connection every request. This is the code that I use for the Strategy. It's exactly the same as in the Nest.js documentation:

However, it only works for HTTP request that exist inside that service. Our microservices are communicating through MessagePattern, so I will have to include the tenantId inside the data context. But it seems to be impossible to retrieve that inside the Strategy code. I've try many ways but I couldn't achieve it. Can someone give me some idea? Thanks

mild nebula
#

But it seems to be impossible to retrieve that inside the Strategy code.
You lost me here. Can you specify a bit better what isn't working?

prime sierra
#

Yes. What I meant is that I tried to do multiple ways to retrieve the data from microservices context inside this AggregateByTenantContextIdStrategy but I just couldn't get the data. What I normally do is @coarse trellis(CONTEXT) as same as the below class. However, the documentation instructed me to register the strategy in the main.ts file, so if I inject the context inside the constructor, it will require me to pass the context argument inside the class called in main.ts file.

Currently, if my services communicate with each other, they will pass tenantId inside the data context, which I can use to be the tenant identifier for my databases. Right now the strategy code can only check the tenantId from HTTP request headers that exist in that service only. If the other services communicate to this one, it won't be able to detect the tenantId

deft tulip
#

I'm going to promote AsyncLocalStorage (https://docs.nestjs.com/recipes/async-local-storage) here again, because I think that all this hassle with request scoped providers is just too complicated, especially when a native Node API exists.

mild nebula
#

@prime sierra - I'm still a bit lost. My understanding is, a strategy like yours can only be used within a gateway. After that, it is up to you to pass on the needed information to your microservices in the message payload.