2013-08-13 14 views
9

Tworzymy interfejsy API przy użyciu ServiceStack, które są wieloma dzierżawcami. Chcemy przeprowadzić równoważenie obciążenia i routing w oparciu o DNS, zamiast łączyć wszystko za pomocą odwrotnego proxy (np. Nginx lub haproxy).Multi-tenant ServiceStack API, to samo wdrożenie do odpowiedzi na żądania na różnych nazwach hostów?

Posiadamy DTO zamówienia, które mają parametr Tenant. ServiceStack (i jego SwaggerFeature) pozwalają nam definiować niestandardowe trasy i dokumentować DTO tak, że możemy odczytać wartości ze ścieżki, zapytania, nagłówków lub treści.

W jaki sposób możemy (najlepiej) łączyć rzeczy tak, aby właściwości DTO mogły również odczytywać wartości z wzorca nazwy hosta? Czy chcesz, aby Trasa przyjmowała wartości z dopasowania nazwy hosta, a także ścieżki?

Chcielibyśmy mieć adresy jak

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

Również - poza strefą DNS będzie się różnić w zależności, które jesteśmy w otoczenie - za brak produkcji używamy (powiedzmy) testing-foobar.com i produkcji używamy real-live.com. Najlepiej byłoby, gdybyśmy poparli obie deklaracje na temat jednej trasy (i wolimy dekorację DTO dla Wniosku zamiast imperatywnej deklaracji w czasie wykonywania AppHost.Init).

+1

Moja pierwsza skłonność polega na używaniu [filtrów zapytań i odpowiedzi] (https://github.com/ServiceStack/ServiceStack/wiki/Request-and-response-filters) Czy rozważałeś je? –

+4

Użyłbym filtrów Request wstrzykujących dowolny DTO Request, który implementuje niestandardowy interfejs 'ITenant', który ma właściwość' Tenant'. Innym rozwiązaniem jest użycie metody rozszerzenia 'IHttpRequest.Tennant()', którą można ponownie wykorzystać we wszystkich usługach kontrolujących właściwości AbsoluteUri lub RawUrl. – mythz

+0

@mythz - czy jest jakiś przykład pokazujący, jak zaimplementować to w ServiceStack? – Marek

Odpowiedz

3

Rozwiązałem to tylko w tym tygodniu, na istniejącym systemie dla wielu dzierżawców, który używa podmiotów zabezpieczeń .NET, aby poradzić sobie z uprawnieniami użytkownika i lokatorami. Użyłem niestandardowego ServiceRunner, aby wybrać dzierżawcę i skonfigurować zabezpieczenia. Twoje podejście do wielu dzierżawców jest inne, ale korzystanie z ServiceRunner nadal wydaje się być dobrym podejściem.

Można by skończyć z czymś takim:

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

Może Wnioski filtrowanie podejście jest jakoś lepiej, ale spełnia swoje zadanie dla nas.

+0

Mamy już IServiceRunner, aby zrobić nasz UnitOfWork - nie sądzę, że te mogą być powiązane –

Powiązane problemy