Skip to content

Instantly share code, notes, and snippets.

@thosakwe
Created December 28, 2017 02:56
Show Gist options
  • Save thosakwe/d1cdf72a05768b3c76e6f21c5bf63846 to your computer and use it in GitHub Desktop.
Save thosakwe/d1cdf72a05768b3c76e6f21c5bf63846 to your computer and use it in GitHub Desktop.
Multi-tenancy Angel middleware
import 'dart:async';
import 'package:angel_framework/angel_framework.dart';
import 'package:mongo_dart/mongo_dart.dart';
/// Chooses the database associated with the [tenantId], and injects it into the [RequestContext].
///
/// @[Header] annotation is used to parse out the `x-tenant` header, if it is not present, a 400 is thrown.
Future<bool> chooseDatabase(@Header('x-tenant') tenantId, Db db, RequestContext req) async {
// Assuming that you have a collection that maps tenant ID's to collection names:
var mapping = await db.collection('tenants').findOne(where.id(new ObjectId.fromHexString(tenantId)));
var connectionString = mapping['connection_string'];
var scopedDb = new Db(connectionString);
await scopedDb.open();
// Once we inject this as a dependency, it can be passed throughout the duration of the request.
req.inject(Db, scopedDb);
return true;
}
import 'dart:async';
import 'package:angel_framework/angel_framework.dart';
import 'package:mongo_dart/mongo_dart.dart';
import 'middleware.dart';
/// Add some pseudo-code routes to the server...
Future configureServer(Angel app) async {
// Call `chain` to apply a middleware
app.chain(chooseDatabase).get('/leads', (Db db, RequestContext req) {
// Since we injected [Db], the value of `db` here is the `scopedDb` from earlier.
// If each tenant has their own database, then the 'leads' collection will pertain only to that tenant.
var leadsCollection = db.collection('leads');
return leadsCollection.findAll();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment