2013-08-13 19 views
9

Çok kiracılı olan ServiceStack kullanarak API'ler oluşturuyoruz. Tersine bir proxy (nginx veya haproxy gibi) yoluyla işleri dikilmek yerine DNS tabanlı yük dengeleme ve yönlendirme yapmak istiyoruz.Birden çok kiracı ServiceStack API'si, farklı ana bilgisayar adlarındaki isteklere yanıt vermek için aynı dağıtım?

Kiracı parametresi olan DTO'lar isteğimiz var. ServiceStack (ve onun SwaggerFeature), özel yolları tanımlamamıza ve DTO'ları yol, sorgu, üstbilgi veya gövdeden değerler okuyabildiğimiz şekilde belgelememize izin verir.

Tel nesneleri, DTO özelliklerinin de bir ana makine adı deseninden değerleri okuyabilmesi için nasıl (en iyi) yapmalı? Bu nedenle, Rota'nın değerleri, ana makine adının yanı sıra yolun dışına çıkmasını sağlayın. DNS bölgesi hangi ortam içinde bulunduğumuz olarak değişecektir dışarı - - olmayan üretim için kullandığımız (diyelim) testing-foobar.com

Biz de

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

gibi URL'leri olmasını istiyorum ve üretim real-live.com kullanıyoruz. İdeal olarak, her ikisini de tek bir rota bildirimi ile destekleyebildik (ve AppHost.Init çalışma zamanında zorunlu bildirim yerine DTO isteğinin dekorasyonunu tercih ediyoruz).

+1

İlk isteğim [istek ve yanıt filtrelerini] kullanmaktır (https://github.com/ServiceStack/ServiceStack/wiki/Request-and-response-filters) Bunları düşündünüz mü? –

+4

Ben sadece bir "Kiracı" özelliği olan bir özel 'ITenant 'arayüzü uygulayan herhangi bir DTO Talep enjekte İste filtreler kullanın. Başka bir çözüm, AbsoluteUri veya RawUrl özelliklerini inceleyen tüm hizmetlerde yeniden kullanabileceğiniz bir 'IHttpRequest.Tennant()' uzantısı yöntemini kullanmaktır. – mythz

+0

@mythz - ServiceStack'ta bunun nasıl uygulanacağını gösteren bir örnek var mı? – Marek

cevap

3

Yalnızca bu hafta, kullanıcı izinleri ve kiracılarla ilgilenmek için .NET güvenlik ilkelerini kullanan varolan bir çoklu kiracı sistemde çözdüm. Kiracıyı seçmek ve güvenliği ayarlamak için özel bir ServiceRunner kullandım. Çok kiracılığa yaklaşımınız farklıdır, ancak bir ServiceRunner kullanmak hala geçerli bir yaklaşım gibi görünmektedir.

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

Belki İstekler filtreleme yaklaşımı nasılsa daha iyi, ama bu bizim için bir iş yapar:

Böyle bir şey ile bitirmek istiyorum.

+0

UnitOfWork'umuzu yapmak için bir IServiceRunner'ımız var - Bunların zincirli olabileceğini sanmıyorum –