2016-03-22 63 views
2

Klasik müşteri sınırlı bağlamına ve MakeCustomerPreferred komutuna sahip olduğumu ve günlüğe kaydetme ve yetkilendirme gibi bazı çapraz kesme endişelerim olduğunu varsayalım. Bu kesişen sorunların üstesinden gelmenin yolu kapsamlı bir şekilde tartışılsa da, kullanıcı hakkında bilgi kaydetmek istediğimiz veya etki alanı olaylarında emri vermekten sorumlu olan hizmeti merak ediyorum.CQRS/ES sisteminde olayları yayınlayan hizmeti ve kullanıcıyı kaydetme

Örnek olay:

interface CustomerMadePreferred { 
    customerId: string, 
    issuingService: string, 
    issuingUser: string, 
} 

Örnek komut:

interface MakeCustomerPreferred { 
    customerId: string 
} 

biz veren kullanıcı ve hizmet detayları içerikten yoksun olacağını Yukarıdaki komutu kullanarak. İstemcinin, komutun bir parçası olarak issuingService ve issuingUser için değer sağlamasını talep edebiliriz, ancak sorun, genellikle istemci tarafından gönderilen komuttur ve bu durumda, istemcinin uygulamanın denetiminin dışında bir web tarayıcısı olduğunu varsayalım Kullanıcının komut içinde hangi değerleri gönderebileceğini kontrol edemeyiz. Ek olarak, bu değerleri genel olarak, Hizmetimiz bir ReSTful veya JSON Web API'sinin arkasındaysa, OAuth jetonları gibi şeyler kullanarak belirleyebiliriz. Bu bana birkaç açık stratejiyle yaklaşıyor.

Olası Stratejiler:

  1. komutla issuingService ve issuingUser ekleyin ve sonra auth bağlamdan belirlenen değerlere karşı onları doğrulamak. Bu, istemci tarafından verilen komutun, işleyici tarafından işlenenle aynı olmasını ve komut işleyicisi uygulamasının yalnızca bir komut parametresine ihtiyaç duyması ve hiçbir kimlik bağlamının geçmemesi açısından basit olmasını sağlar.
  2. Özniteliği issuingService ve issuingUser auth bağlamından ve bu ayrıntıları, komut işleyicisine teslim edilen komutlara ekledik/ekledik. Bu, orijinal komutu veren istemcilerde daha kolay olur, ancak komutun sözleşmesi, komut işleyicisi ile istemci arasında biraz farklıdır. Örnek:
  3. Auth içeriğini komut işleyicisine ayrı bir argüman olarak aktarın veya komut işleyicisi tarafından çağrılabilen bir hizmetten edinebilirsiniz. Bu, komutun sözleşmesini korur, ancak komut işleyici uygulamasını zorlaştırır.

seçeneklerim ve komut işleyicisi uygulanmasına işlevsel bir yaklaşım için izin görünüyor başlıca nedeni yönünde eğilim var. Belki de bazı seçeneklerden ayrılıyorum veya issuingService ve issuingUser dahil olmak üzere olaylarda gereksiz olabilecek bazı detaylara bakıyorum.

GÜNCELLEME: Bir alternatif olarak, oluşturulan bu ayrıntıları içermeyecek şekilde olabilir, opsiyon arama sağlar olayı CustomerMadePreferred ve bunun yerine işlemek ve bazı tür bir anahtar içerebilir ayrı CommandIssued olayları yaydığını yayıncı bilgisini komut işleyici tarafından yayılan olaylarla ilişkilendirmek için kullanılabilir.

+0

Teknik uygulamaya göre, aynı konu hakkında düşündüğümde planım, etkinliğe bazı meta veriler eklemektir. Böylece etkinlik bir alan adı olarak kalacaktır ancak içeriği tanımlamak için bazı teknik meta veriler ekleyebilirim. –

+0

@jpierson 2. ve 3. arasında herhangi bir fark yoktur * şu kadarıyla komut, komut işleyicisi ile istemci arasında biraz farklıdır *, var mı? – guillaume31

+0

@ guillaume31, 2 ve 3 arasındaki farklar belki de süptildir, ancak bunlar etrafında birim testi yazılması veya komuta türlerinin etrafındaki diğer yansıtıcı aletlerle ilgili nasıl bir şey olabileceği açısından büyük ölçüde etkilenecektir. Komut işleyici sınıflarının/işlevlerinin sözleşmesi de arasında etkilenecektir. – jpierson

cevap

1

Neredeyse seçenek 4'ü severim - hislerim korelasyon ID'si yanlış mekanizmadır. Bunun yerine bir nedensellik kimliği kullanırdım; Korelasyon kimliği, biraz farklı bir anlam ifade eder. Command.id:N tarafından üretilen tüm olayların olayı olurdu.causationId: N ve etki alanı dışındaki herhangi bir endişeyi kontrol etmek için komut geçmişine (etki alanının dışı) geri dönebilirsiniz.

Muhtemelen,'un bu bilgileri yakalamak istediği 'a bakmanız gerekir. Eğer devOps ekibinizse, etki alanı olaylarını temiz tutmak muhtemelen doğru seçimdir, sadece yukarıda açıklandığı gibi komut geçmişine bağlantı.

Eğer alan uzmanlarınız bunu isteyenler ise, bu da kaşları yükseltmelidir, çünkü burada mevcut olan dilin dışına çıkması ve modelinize dahil edilmesi gereken alan gizleme kavramları olduğunu düşündürmektedir.

(Don't Create Aggregate Roots ile karşılaştırın; müşteri hesabına değişiklikler hiçbir şey gelmeyen onlar gerçekten etki alanı içinde çıkıyorlar Eğer öyleyse, o zaman muhtemelen izlenecek istiyor.?.)

+0

Harika puan! Ben causationId terimini severim, ben de verilen bir komut için olayları ilişkilendirmek kavramını tanımlamak için kullanılan _originating komut_ ifade duydum. Benim durumumda, olaylarla ilgili bu tür bilgilerin nasıl ekleneceği veya dahil edilip edilmeyeceği sorusu, alan adı uzmanlarının doğrudan bir endişeden daha fazla bir _developer_ veya _operational_ endişesi olduğunu düşünmektedir. – jpierson

1

Genellikle sonunda Kimlik doğrulama bağlamını doğrudan komut işleyicide en az karmaşık bir çözüm olarak (sizin durumunuza göre 2. veya 3. eşleşip eşleşmediğinden emin değilim) ulaşarak. İstemci ve sunucu arasında farklı olan komut yapısı benim durumumda bir sorun değil, çünkü istemci kendi başına komut göndermiyor, (HTTP kaynağı, fiil, içerik türü) aracılığıyla bunu temsil ediyorum.

+0

Bunu da düşünüyordum. Komut kontratının müşteriye ne kadar maruz kaldığına ve GET/POST ile sınırlı olan ya da bahsettiğiniz HTTP olanaklarından yararlanarak daha fazla RPC stili takip edip etmediğine bağlı olduğunu düşünüyorum. – jpierson