1

Scenario A: Suppose you have several databases on the same SQL Server/SQL Azure instance sharing the exact same structure, where the database names are convention based, like db001, db002, ... and a single RESTier service must be able to address the correct database for each REST call, depending on some characteristic to be provided on the request header or on the URI path or query string.

Scenario B: A single RESTier service must be able to address more than one connection string, defined on the web.config file, depending on some characteristic to be provided on the request.

In both scenarios the base issue is the same, a single RESTier service to be able to address requests for more than one database, where the client must submit on each request a hint to the database to be used, a typical multitenant scenario. I'm using RESTier version 0.6 and the entity sets are automatically exposed from a Entity Framework model:

public class Entities : EntityFrameworkApi<SalesEntities> { 

Question is, how would you advise to implement this kind of multi-tenant scenarios?

Alberto Silva
  • 382
  • 3
  • 12

2 Answers2

1

You could use a parameterized routePrefix like below and parse that part of the URL (HttpContext.Current.Request.RawUrl).

config.MapRestierRoute<Entities>("EntitiesApi", "api/{entitiesConfig}", new RestierBatchHandler(server)); 

Retrieve the correct connectionString from your Web.config and use that to create the DbContext:

Match match = Regex.Match(HttpContext.Current.Request.RawUrl, @"/api/(?<entitiesConfig>[A-Za-z0-9\-]+)/", RegexOptions.IgnoreCase);
string entitiesConfig = "DefaultEntitiesContext";
if (match.Success)
    entitiesConfig = match.Groups["entitiesConfig"];
string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[entitiesConfig].ConnectionString;
var db = new SalesEntities(connectionString);
Sander
  • 161
  • 1
  • 5
  • Thanks for your reply, have you tried it yourself in RESTier, and if so, in which version? I'm no longer working with RESTier, but other who end up in this page could benefit from your suggestion. – Alberto Silva Jan 18 '19 at 15:26
  • 1
    Yes, I am using this myself in RESTier 0.6.0. I have changed the code to match your example. – Sander Jan 20 '19 at 06:34
0

For your scenario, I think you will have two DbContext, each one connect to one DB instance, then will something like this will work for you?

In the configure method, we call MapRestierRoute twice, and each one will handle one DbContext with different route prefix, and when user initiate the request, the request URL will contain prefix and will auto route to related DB instance.

config.MapRestierRoute>( "TrippinApi", "api/TrippinA", new RestierBatchHandler(server)); config.MapRestierRoute>( "TrippinApi", "api/TrippinB", new RestierBatchHandler(server));

Let me if you have any issues with this.

Vincent
  • 340
  • 2
  • 11
  • Have to admit that I haven't found how to use the route prefix ("TrippinA", "TrippinB") to be able to pick the correspondent database instance (let's say, "DBTrippinA", "DBTrippinB"), so that the following two requests are targeted to different databases over the same RESTier controller: http://myServer/api/TrippinA/Products http://myServer/api/TrippinB/Products – Alberto Silva Sep 29 '16 at 11:10
  • For each DBInstance, you should have used code first and create two class with extends DBContext, each DbContext related to one DbInstance. During route map, each route is related to one DbContext. In this way, we can make route related to DbContext. But note this is not auto configured, but configured during application start. – Vincent Oct 07 '16 at 08:02
  • That would imply that I must determine in advance the maximum number of tenants that I'm willing to support (10 tenants means 10 DbContexts means 10 hardcoded routes), which as multi-tenancy approach doesn't make much sense to me. – Alberto Silva Oct 08 '16 at 14:06