Latest Replies
Monday
Mar042013

Aggregate Design and Security

Answering a question from the community:

How do you handle security concern of sending aggregate id to the web client? What'd you do to ensure I can't, from the browser or another client, manually send aggregate id that belongs to another client to either get some data about it or send some commands to mess things up?

Each specific system scenario would lead to the specific design. If our specific scenario is:

  • business logic is hosted on Application Server (e.g. hosted in Lokad.CQRS) which we control trust;
  • client UI is hosted on Web server UI which we control and trust; Web server accesses application server (by sending commands and polling views) and renders HTML to user's browser.

Then the solution to the security concerns problem is:

  • We don't trust client browser anything (except from keeping unique token)
  • we trust Web server UI to authenticate user (ensuring that he is who he claims to be). In this web App we will ensure that client sends only commands to the aggregates he is allowed to access (while checking commands as well).
  • In app service we don't do any deep security checks and just carry out the commands.

This scenario works well in simple situations where we have an app server and a few Web UI servers (alternatively with REST API servers), managed by the same team and hosted in the same controlled environment.

If we have a different environment (e.g. application server can't trust web server), then a different separation of responsibilities might be needed. For example, we might need to perform authentication within the methods of Application service (checking that user is who he claims to be), while pushing authorisation down to method calls on an aggregate (checking that user can do what he attempts to do).

In this scenario, authorisation might be encapsulated within an instance of domain service, passed down by application service to a method on aggregate. This service would have access to permission maps (or any other way of representing role/permission information), aggregate would call it's methods to find out if the specific user can perform requested actions on the requested resources.

Naturally, in this case, Web UI must still ensure that we don't send illegal commands to the server. The difference from the first scenario is - we don't trust the web server to be diligent.

These and other specifics of project environment, team organisation and trust can have a great impact on development process and product design.

Wednesday
Feb272013

What's new in #DDDesign

Quite a lot has changed since the last post.

The official web site of DDD community has got a brand new look, making it more convenient for looking up existing resources, sharing and connecting. Check it out and follow the twitter account.

Implementing Domain-Driven Design book with from Vaughn Vernon with foreword by Eric Evans is now available on Amazon as printed or Kindle edition (Addison-Wesley series).

More than 20 episodes of Being The Worst Podcast were published since the last update of DDDesign news. We went deeper into practical use of Domain-Driven Design and event sourcing. Here are highlights of some new episodes:

  • Episode 4 - Event Sourcing Basics

    We review questions about designing command and event messages and then introduce the new topic of Event Sourcing. We model one day at the Factory using event sourcing, domain language and concepts discussed in earlier episodes.

  • Episode 5 - Aggregating Stories

    We introduce the concept of aggregates and their importance to the design of distributed systems. Then, we describe another way to express the story of an aggregate, through the use of specifications and the testing of use cases.

  • Episode 6 – Community Code and Questions 1

    We discuss community questions about naming messages, aggregate state, and event implementation.

Podcast episodes are accompanied by source code samples in C# (with community contributions covering other languages). They are available for download on github.

Another newsletter from Domain Language came out in November 2012. It contains a reference to video by Julie Lerman where she gives some practical advice on how to keep contexts separate in an EF application, with a nice concrete example.

Friday
Jan252013

Utility Classes are Lesser Evils

Generally, code reusability (and Don't Repeat Yourself principle) are a big evil, if used without constraint. They can couple together really distant concepts, while increasing overall complexity of the code.

Did you ever have an utility class, which was introduced for a single purpose, but ended doing up everything at once?

That's why at Lokad we try to avoid utility classes. Especially if they have only a few uses spread across different parts of the project. Such code can be inlined instead.

However, sometimes, utility method is relatively complex and big. Plus, it can be used in too many places inside a single project. In such case we agree to introduce utility class (which is internal for this project) and put it into well-defined location (folder and/or namespace) called "LesserEvils", while adding "Evil" suffix to the class names.

Name somehow allows us to stay more conscious about abuse of common utility classes and potential coupling they can introduce into a project. Lesser of evils is still an evil.

Thursday
Jan242013

Essence of Domain-Driven Design - Re-Explained

This question came from the latest episode of Being The Worst: Linguistic Cartographers from Johan. In that episode Kerry and I tried to apply DDD to the exploration of new domain.

First of all thanks for a great podcast series, I’m always looking forward to the next episode! I’m just a little confused when it comes to bounded contexts, domains and services (SOA term). From what I understand when listening to an episode of the “Distributed Podcast” with Udi Dahan, bounded contexts in DDD terms are more or less interchangeable with services in SOA terms. If I remember it correctly Udi also said that you should only use CQRS in those BCs/services that are in a collaborative domain. In DDD terms the BC is a linguistic boundary (am I right?) which makes sense when I look at your context map. What I don’t really understand is what Udi means when he says that CQRS should (only) be used in certain BCs. To me it seems like CQRS may be used in a certain domain (like a core domain) that resides inside a certain BC. Other domains in the same BC may or may not use CQRS. Have I understood it correctly or am I misstaken? Sorry if the question is a bit off topic.

We will be talking about some of these concepts in later episodes (some already recorded), but let's get this straight in writing. We'll try to stick to the original definitions as heard from Eric Evans, Vaughn Vernon and Gregory Young. Here's my interpretation, which tries to stay as close to the origins as possible.

We apply Domain-Driven Design to help solving problems in some vast and complicated problem space. This problem space is called Domain or "the Business" - how people actually do things in the real world.

While doing DDD, we try to divide the large problem space in smaller and more manageable regions, which can be conquered separately. We identify these regions just like how cartographers identify places - by looking at some shared traits. In our case: language used by experts, organisational boundaries, existing common knowledge etc. These regions are called bounded contexts.

We identify existing solutions (applications, components, projects) and plan our new solutions. Usually existing solutions are developed without the regard to bounded contexts. Ideally, new solutions would fit precisely into the problem regions we identified. However existing solutions can overlap or have various sorts of ugly shapes. These solutions are called subdomains.

The process of first identifying problem space and currently existing solutions, then, mapping it to some picture is called context mapping. It is extremely important, since it provides you with the strategic overview of your battlefield, helping to prioritise and make decisions. Context Map is not a view of the future, but rather a current state.

One of the most important traits used in identifying boundaries is language of the problem space, choice of terms and words, which are used by experts. We would try to use the same language while talking with them, with domain experts and all the way through the solution process. This will drastically reduce the confusion. Language is called Ubiquitous Language. The idea is to use this language as a way to explore our Domain and, with the help of the Domain experts, capture it in a Domain Model - a useful abstraction of the business, captured in the code.

While building new subdomains for the identified bounded contexts, we try to develop them in such a way, that the solution would be tightly linked to the original problem. This will make it more robust, understandable and evolution-tolerant; real, in other words. Ideally, language of the problem space (along with the boundaries) will find it's way into the solution, including name of projects, classes and methods. Being The Worst podcast talks about the practical side of such development quite a bit.

We can't address all problems at once, so different solutions will have different priorities. They will also have different possible implementations. Hence, we can differentiate in subdomains:

  • Core domain - the most important subdomain, which is essential for the business. Without it the business would fail. If you ever need to pick the first solution to implement - start with the core domain.
  • Supporting subdomain - subdomain, which is less valuable for business than Core domain. Without it business may be can even survive for some time. But it still is quite important (supports core domain), it also is specific for the domain and has to be developed. In this case, for some reason, we can't buy an existing software or component to solve the problem.
  • Generic subdomain - subdomain which is less valuable for business than Core domain. It also is generic enough to allow buying it off the shelf (unlike supporting domain).

While building solutions for the specific problems, we can optimise our solutions by picking the best tooling, approaches, methodologies from the available. For example, CQRS with Event Sourcing might be a good fit for the Core Domain, while CRUD SQL system can be the best fit for another. These different methodologies will not conflict or confuse people, since we explicitly keep them within the subdomain boundaries.

Also, while talking about Context Maps, we can identify relations between different subdomains, based on the real-world situation. It might include politics, organisational boundaries, personal distrust between teams or tight budgets. Considering these factors can help to identify potential issues in advance, while also baking in work-arounds and contingency plans into the actual software being developed. We can also identify potential integration and extensibility points. Here are some of the common terms used:

  • Published Language - linguistic elements (e.g. command and event contracts) that are frozen and made visible outside of the subdomain. This way other subdomains can interact with it.
  • Shared Kernel - part of the subdomain implementation that is frozen and extracted (so that the others can reuse and integrate with it better).
  • Anti-Corruption Layer - Code, which explicitly protects logical model of a subdomain from messy logic or changes in other subdomains, it has to integrate with.

Once again, Essence of Domain-Driven Design is not about some patterns (i.e.: repositories, value objects, event sourcing etc), it is about looking at complex real world problems, learning how to break them down into smaller pieces and then solving them in the most efficient way. DDD teaches methodologies that help to move along this process.

Ideally, for each bounded context, there will be one subdomain that fit's it perfectly. Although this might work for green-field projects, in reality the situation can be different. This especially is true in legacy systems.

In legacy systems, entire problem space can be treated as one big and complex problem, with a few solutions thrown there and there without any explicit reasoning or boundaries. In this case we can have one messy and confusing bounded context with a bunch of subdomains stepping on each other's toes. DDD also provides guidance on gradually getting out of this mess.

Please, keep in mind, that these definitions are my own personal interpretations, presented in the simplified form. If you want to go to the roots - check out the Blue Book by Eric Evans

PS: And no, Bounded Contexts are not interchangeable with services in SOA terms. The former is the problem, the latter is the solution.

Update: there is an episode of Being the worst podcast which goes into more detail on this topic.

Monday
Jan212013

Lokad.CQRS Event Store is Slow

I keep on getting questions about the performance of the event store in Lokad.CQRS Sample project. Long story short, it does not kick ass per se.

Currently event store in Lokad.CQRS is a sample implementation of append-only storage (either to file system or to azure blobs) with in-memory caching of all events to allow fast querying by event stream ID. It has a decent performance for small systems, where you have one node (with multiple threads) writing to the disk (Azure blob or file system, depending on the config). Startup times can be a bit slow (especially if store got too fragmented between chunks), since it has to warm up all the caches. All reads are executed against memory (and hence are really fast). Writes directly to the underlying storage (Azure or disk buffer). I'd say that you can expect 80 events per second on Azure and 400 events per second on file system. We don't buffer anything, which would significantly increase performance and also introduce slightly higher risk of loosing data on system failure.

This all is expected, since Lokad.CQRS ES is designed to be simple, understandable and good enough for small projects. If you need something more robust, here are the options:

  • Check out Event Store of Gregory Young
  • Consider persisting your event streams in some existing data storage (e.g.: Redis should work really nicely with such code)
  • Wait till Lokad adds event sourcing support to it's Data Platform project (storing gigabytes of data with a decent performance and while leveraging capabilities of Windows Azure; potentially capable or supporting elastic storage grid with millions of partitioned writes per second).

Also, if you want to learn more about underlying principles of append-only storage and performance trade-offs, please read this amazing article about Redis persistence.

Saturday
Jan192013

Sorry, Skipping IDDD Tour in Europe

I'm sorry but I'll have to withdraw from IDDD Tour in Europe. My personal circumstances have changed and this prevents me from participating.

I guess, Vaughn will still keep the same 4-day format of event, replacing my 1 day of presentation with some other material to compliment his book. If there are any people who signed up to the event only because of this A+ES Appendix talk (which I doubt, since it is a minor material), don't hesitate to ask for a refund.

There is always a Being The Worst podcast, provided to community for free. If you have any questions on A+ES topic and if they were not addressed in the episodes so far, don't hesitate to ask them in comments to the episodes or in Lokad google group. We always try to address them as thoroughly as possible.

My apologies for not being able to make it.

PS: I'll still try to make it to Belgium and Denmark one day.

Thursday
Dec132012

Lokad is looking for Data Developer in Ufa

Lokad ищет C# разработчика с уверенным знанием английского для проектов по интеграции с клиентами (FTP, TSV, SQL, Web Scraping). Офис в Сипайлово (Жукова 22, напротив ОКЕЙ), работа в команде.

Требования

  • Практическое и уверенное знание C#, ООП, шаблонов проектирования.
  • Технический английский письменно (читать и писать без Google Translate)
  • Желание учиться и работать в коллективе
  • Наличие законченных проектов (самостоятельно или в сотрудничестве)
  • Знать и уметь работать с SQL базами данных (запросы и их оптимизация)

Плюсы

  • наличие open source проектов
  • практическое знание extreme programming
  • ASP.NET MVC.

Примеры задач

Примеры задач (объемы данных от мегабайтов до терабайтов):

  • Написать парсер для TSV/CSV файлов, предоставленных клиентом.
  • Разобраться в Базе Данных клиента и разработать программу для автоматического импорта новых и изменившихся данных из нее в TSV файлы.
  • Оптимизировать алгоритмы работы с данными для эффективного использования оперативной памяти, дискового пространства и времени процессора.
  • Тестировать и поддерживать системы по интеграции данных
  • Написать Web Scraper для веб-сайта клиента, чтобы импортировать данные (иногда и такое приходится делать).
  • Экспортировать результаты вычислений в SQL/NoSQL базы.

Возможность обучения в процессе работы:

  • Принципы разработки и масштабирования сложных систем
  • Big Data
  • Cloud computing
  • DDD / CQRS / Event Sourcing

Зарплата от 30000 руб.

О Lokad

Контакты

Если предложение интересно, присылайте резюме на contact@lokad.com