2013-08-13 11 views
9

Stiamo creando API utilizzando ServiceStack che sono multi-tenant. Vogliamo eseguire il bilanciamento del carico basato su DNS e il routing, invece di ricucire le cose tramite un proxy inverso (come nginx o haproxy).API multi-tenant ServiceStack, stessa distribuzione per rispondere alle richieste su nomi host diversi?

Abbiamo richieste DTO con un parametro Tenant. ServiceStack (e la sua caratteristica Swagger) ci consente di definire percorsi personalizzati e documentare le DTO in modo tale che possiamo leggere i valori da percorso, query, intestazioni o corpo.

In che modo (meglio) cabliamo le cose in modo che le proprietà DTO possano leggere anche i valori di un pattern di nome host? Quindi, fai in modo che il percorso prenda i valori dalla corrispondenza tra nome host e percorso?

Ci piacerebbe avere gli URL come

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

Inoltre - out zone DNS può variare a seconda dell'ambiente che siamo in - per i non-produzione utilizziamo (diciamo) testing-foobar.com e produzione usiamo real-live.com. Idealmente saremmo in grado di supportare entrambi con una singola dichiarazione di percorso (e preferiamo decorare il DTO della richiesta anziché la dichiarazione imperativa in fase di esecuzione AppHost.Init).

+1

La mia prima inclinazione è quella di utilizzare [filtri richiesta e risposta] (https://github.com/ServiceStack/ServiceStack/wiki/Request-and-response-filters) Li hai considerati? –

+4

Utilizzerei un filtro Request per iniettare qualsiasi DTO di richiesta che implementa un'interfaccia 'ITenant' personalizzata che abbia solo una proprietà' Tenant'. Un'altra soluzione consiste nell'utilizzare un metodo di estensione 'IHttpRequest.Tennant()' che è possibile riutilizzare in tutti i servizi che ispezionano le proprietà AbsoluteUri o RawUrl. – mythz

+0

@mythz: c'è un esempio da qualche parte in cui viene illustrato come implementarlo in ServiceStack? – Marek

risposta

3

Ho risolto questo solo questa settimana, su un sistema multi-tenant esistente che utilizza le identità di sicurezza .NET per gestire le autorizzazioni e gli inquilini dell'utente. Ho usato un ServiceRunner personalizzato per selezionare l'inquilino e impostare la sicurezza. Il tuo approccio al multi-tenant è diverso, ma l'utilizzo di un ServiceRunner sembra ancora un approccio valido.

ci si finisce con qualcosa di simile:

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) 
    { 
     ... 
    } 
} 

Forse l'approccio di filtraggio richieste è in qualche modo migliore, ma questo fa il lavoro per noi.

+0

Abbiamo già un IServiceRunner per fare il nostro UnitOfWork - Non penso che quelli possano essere incatenati –

Problemi correlati