2013-08-13 4 views
9

Wir erstellen APIs mit ServiceStack, die mandantenfähig sind. Wir wollen DNS-basiertes Load-Balancing und Routing durchführen, anstatt Dinge über einen Reverse-Proxy (wie nginx oder haproxy) zusammenzufassen.Multi-Tenant-ServiceStack-API, dieselbe Bereitstellung, um auf Anforderungen auf verschiedenen Hostnamen zu antworten?

Wir haben DTOs anfordern, die einen Tenant-Parameter haben. Mit ServiceStack (und seinem SwaggerFeature) können wir benutzerdefinierte Routen definieren und die DTOs so dokumentieren, dass wir Werte aus Pfad, Abfrage, Kopfzeilen oder Text lesen können.

Wie verbinden wir (am besten) Dinge, damit DTO-Eigenschaften auch Werte aus einem Hostnamenmuster lesen können? Also, machen Sie die Route nehmen Werte von Übereinstimmung aus dem Hostnamen sowie den Pfad?

Wir möchten URLs haben, wie

  • https://{tenant}.{DNS zone for environment}/{rest of path with tokens}

auch - aus DNS-Zone, in der Umgebung sind wir variieren je - für Nicht-Produktion verwenden wir (sagen wir) testing-foobar.com und Produktion verwenden wir real-live.com. Idealerweise können wir beide mit einer einzelnen Routen-Deklaration unterstützen (und bevorzugen es, das Anfrage-DTO anstelle der imperativen Deklaration zur Laufzeit zu dekorieren AppHost.Init).

+1

Meine erste Neigung ist es, [Anfrage und Antwort-Filter] (https://github.com/ServiceStack/ServiceStack/wiki/Request-and-Response-Filters) Haben Sie sie in Betracht gezogen? –

+4

Ich würde einen Request-Filter verwenden, der ein Anforderungs-DTO injiziert, das eine benutzerdefinierte 'ITenant'-Schnittstelle implementiert, die nur eine' Tenant'-Eigenschaft hat. Eine andere Lösung besteht darin, eine Erweiterungsmethode "IHttpRequest.Tennant()" zu verwenden, die Sie in allen Diensten erneut verwenden können, um die Eigenschaften AbsoluteUri oder RawUrl zu überprüfen. – mythz

+0

@mythz - Gibt es irgendwo ein Beispiel, das zeigt, wie man dies in ServiceStack implementiert? – Marek

Antwort

3

Ich löste dies nur diese Woche, auf einem bestehenden Multi-Tenant-System, das .NET-Sicherheitsprinzipale verwendet, um mit den Benutzerberechtigungen und Mandanten umzugehen. Ich habe einen benutzerdefinierten ServiceRunner verwendet, um den Mandanten auszuwählen und die Sicherheit einzurichten. Ihr Ansatz zu Multi-Tenant ist anders, aber die Verwendung eines ServiceRunner scheint immer noch ein gültiger Ansatz zu sein.

würden Sie mit etwas am Ende wie folgt:

public class MyServiceRunner<T> : ServiceRunner<T> 
{ 
    public MyServiceRunner(IAppHost appHost, ActionContext actionContext) 
     : base(appHost, actionContext) 
    {} 

    public override void BeforeEachRequest(IRequestContext requestContext, T request) 
    { 
     // Set backend authentication before the requests are processed. 
     if(request instanceof ITenantRequest) 
     { 
      Uri uri = new Uri(requestContext.AbsoluteUri); 
      string tenant = uri.Host; // Or whatever logic you need... 
      ((ITenantRequest).Tenant = tenant; 
     } 
    } 
} 

public class MyAppHost : AppHostBase 
{ 
    public MyAppHost() : base("My Web Services", typeof(MyService).Assembly) { } 

    public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext) 
    { 
     return new MyServiceRunner<TRequest>(this, actionContext); 
    } 

    public override void Configure(Container container) 
    { 
     ... 
    } 
} 

Vielleicht ist die Anfragen Filterung Ansatz irgendwie besser ist, aber das macht die Arbeit für uns.

+0

Wir haben bereits einen IServiceRunner für unser UnitOfWork - ich glaube nicht, dass diese gekettet werden können –