New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request scoped connections #65
Comments
Great idea. We'll likely implement this at some point. For those who are looking for a workaround, you can always create your own |
Is it a good idea to provide new connection per request? Let's check docs: As you can see mongo driver created connection pool under the hood after init app and provided db object for sharing it across app. Creating connection pool per request is a bad idea. As a workaround we can use mongo transactions (which work only with 4.x version and only with replica set) + CLS. |
@DenisPalchuk I think this may depends on the case! currently i could this make it work but using MongooseModule and mongoose lib per-sé, which I think is a big force! Check this! But here in same project i used NestJS MongooseModule because it doesn't have I'd like to use just NestJS MongooseModule with custom provider ( What do you think? |
I need this feature too. I think the |
I did a simple implementation for nest-mongodb, please check it out The main changes are in I test it and it works with Request scoped |
@AliYusuf95 Can you implement your solution in the @nestjs/mongoose module? |
Small update to @aneudysamparo solution which is similar to what i followed, but modified the code for returning any existing connection instead of creating a new one for every concurrent requests. import * as mongoose from 'mongoose';
import { Connection } from 'mongoose';
import { REQUEST } from '@nestjs/core';
import { Scope, NotFoundException } from '@nestjs/common';
import { TenantsService } from '../tenants/tenant.service';
export const databaseProviders = [
{
provide: 'DATABASE_CONNECTION',
scope: Scope.REQUEST,
useFactory: async (req, tenants: TenantsService): Promise<typeof mongoose> => {
if (req.subdomains[0] && req.subdomains[0] !== undefined && req.subdomains[0] !== 'undefined') {
const tenantDB: string = req.subdomains[0];
let foundTenant = await tenants.findOne({ subdomain: tenantDB });
if (!foundTenant) {
throw new NotFoundException('AppName does not exits');
}
// Check if is actived
console.log(foundTenant);
// Get the underlying mongoose connections
const connections: Connection[] = mongoose.connections;
// Find existing connection
const foundConn = connections.find((con: Connection) => {
return con.name === tenantDB;
});
// Return the same connection if it exist
if (foundConn && foundConn.readyState === 1) {
return foundConn;
}
return mongoose.createConnection(`mongodb://localhost/${foundTenant.tenantdb}`, { useNewUrlParser: true });
} else {
return mongoose.createConnection(`mongodb://localhost/TodoAppDB`, { useNewUrlParser: true });
}
},
inject: [REQUEST, TenantsService]
}
]; |
I've made a PR that contributes to this feature request, you can see at: #229 |
Hi @marluanespiritusanto can you please provide an example reference on how to use it. |
I've just published a gist of a multi-tenant mongoose module for nest. I'm relatively new to Nest and I'd like to have your feedback. @kamilmysliwiec is that something valid? |
It looks great at first sight :) @adriano-di-giovanni Think about writing an article about it, I think many people would be interested! |
@adriano-di-giovanni Thats a nice implementation. Would love to see an article about it like @kamilmysliwiec said, as many of us are waiting for an approach on Multi-tenancy using Nestjs. I have tried multiple approaches on this using |
I have put together a library based on @adriano-di-giovanni gist and made some modifications to it. Here is the repository nest-tenancy. Would love to hear your comments on it @kamilmysliwiec |
I spent the whole day trying to figure out the best way to implement this. To try out I took the concept from @adriano-di-giovanni and lib from @sandeepsuvit and implemented a fully working solution. I've added two global guards, one for jwt auth and another to ensure tenancy. Both are applied at global level and ignore the /auth/login endpoint. For any other endpoint TenancyGuard will make sure tenancy present in header and the jwt token are equal. This takes away the vulnerability where you can access other tenants once you are logged into one by altering headers. Many thanks to all the contributors. |
I had tried to implement this in several ways, but I don't fee it the right way to do it.
The last two points which make things hard, they are critical to me since I don't want to recreate the services and all other components for each request -it should be efficient- and I want use the right connection easily. Since the request is only available in the controller and the previous stages, without having But the usage of the connection will not we seamlessly like what this library offers, where the mongoose model is injected directly in the service instead of the connections store. Also, we have to pass the (request/user/tenant ref) to the service if we want to avoid the |
Thanks for your suggestion! This has been discussed in the past and we decided to not implement it in the foreseeable future. If you think your request could live outside Nest's scope, we'd encourage you to collaborate with the community on publishing it as an open source package. |
I'm submitting a...
Current behavior
The connection is created as a singleton
Expected behavior
The connection options support
scope
(https://docs.nestjs.com/fundamentals/injection-scopes) to be defined as per request.What is the motivation / use case for changing the behavior?
I'd like to open an isolated connection on every HTTP requests.
Environment
The text was updated successfully, but these errors were encountered: