@sam how is Space bringing DDD, because of the modularity?
I still don’t get DDD 100%. Do you have simple example comparing the DDD vs other approaches?
Yeah we will upgrade the app to 1.3 - and our priority #1 is going to make code that’s small and easy to understand.
Consider Mercadera to be the anti-architecture bloat project. There are tradeoffs, but obviously I think the tradeoffs are worth it. For example, using our structure, it may not be as easy to switch data stores. Do I think that’s important, not really. That’s just one example.
Things like this, don’t make sense to me. Too much indirection.
// From meteor.space:
var library = { sayHello: function() { console.log('hello!'); } };
var injector = new Space.Injector();
injector.map('OtherCode').to(library);
injector.injectInto(dependentObject);
dependentObject.sayHello(); // logs: 'hello!'
Our key intention: Make the code easy to understand.
Haha - then you must be happy that MDG hasn’t let Mr. Spring Framework bias their architectural decisions …
Totally agree. I also think it’s important that Meteor not lose the one thing that attracted so many people to it: simplicity.
Actually in my post, I said it was not bleeding edge. It does use 1.3 beta, but I also wanted to keep the boilerplate “safe” and somewhat close to MDG’s official guidelines.
Here’s how Space is bringing DDD to Meteor
Have a look at this example .Net app for a good DDD example:
As the maker of Space Kitty, I would recommend sticking with Mantra. There is a lot still the pipeline that I will be changing in order to move more toward the Mantra structure.
The most of the people dont need it.
In my last project I had a introduction to Space (offered by Darko, one of the creators and a briliant dev). 98% of Meteor webs (and web development in general) dont need a usually so complex architecture.
With MVC in the client, and a REST api in the server with a place to put some business rules is enough as I said in the 98% (sure more) of the cases. If you are going to port Wordpress to Meteor or something like that take care of it but if not…why do I need anyhing like that?
Wow @oscarcalvo, you seem to be pretty sure about knowing 98% of all Meteor apps out there
In reality most commercial projects tend to get complex very fast, as business requires a bit more than a todo app. I would recommend to build throw-away prototypes first but start decoupling obviously distinct parts of your app early, it’s no fun to refactor a big ball of mud (= a lot of Meteor apps out there!) after it launched.
One big problem for real businesses is that they cannot predict what questions they will have or how data needs to presented in the future. So the obvious best case scenario is that your system records everything that happens (= you can answer any possible question about your system, from day 1) and makes it easy to restructure your UI data model at any time (= present data in any way possible). In a nutshell, this is what Space is designed to help you with.
We are working on the documentation of Space, but you can read the high-level pitch here:
By the way, these frameworks are not exclusive in any way. We have one project that uses Meteor 1.3 with Space + Mantra / React without any issues
@PolGuixe: Space works really well with meteor 1.3.
I am currently working on new, big and exiting project with a very complex business domain. We where very careful with architectural and design choices to make the product we are building as future proof as possible.
Project is running Meteor 1.3 with Mantra/React on frontend and Space DDD/ES/CQRS on backend.
We are expecting for this project to grow and evolve rapidly and without Event Sourcing that would be hard or impossible to manage. Choice to use Space ES for the backed is really paying off in this project.
One big problem for real businesses is that they cannot predict what questions they will have or how data needs to presented in the future. So the obvious best case scenario is that your system records everything that happens (= you can answer any possible question about your system, from day 1) and makes it easy to restructure your UI data model at any time (= present data in any way possible). In a nutshell, this is what Space is designed to help you with.
We are keeping domain events simple which is in line with our business requirements and that is helping us to build this product rapidly and with great flexibility.
I am not able to give concrete examples since there is an NDA in place. But for an illustration when our customer creates a new project in our product it can be created with minimal attributes and as more information becomes available it is added gradually and new domain events are stored in the ES commit store. So we are gradually introducing new domain commands and domain events as our product functionalities expand and that is not in collision with previously implemented functionalities. Every serialisable structure in Space can also change and evolve since Space has Versionable mixin. So initially everything is at version 1, and when we decide to change domain events than we increment a version to 2 and provide a transformFromVersion1
method.
Projections are generating view cache from domain events.
Projections are really the key selling point in Event Sourced system. With projections we are able to have unlimited denormalised read models.
Projections give us lot of great things
-
Snappy and “dumb” UI: we have dedicated collection and projection for every screen in our application and document in that collection for every organisation and user in our system. For example “list of tasks for user X”, “list of project for organisation X”, “chat messages for user X”. To illustrate this even further consider this scenario. Someone sends a chat message in the channel to all people on some project team. One simple domain event is stored in the commit store, eg:
ChatMessageSent: {sender: userId, message: message, projectId: projectId}
. Projections generate documents for every team member in dedicated collection which stores chat messages. UI just reads it. - There are no worries about managing duplicated or stale data. The only place where “real” system state is stored is the Domain Event commit store.
- UI can evolve rapidly: if read requirements change (as they often do in quick-evolving systems), or bug is detected in projection logic, projected data can be dumped, new or changed projection logic can be put in place, and system can go in a rebuild mode which reads every event from the store and sends it over the event buss, projections handle those events (subscribe and listen) and populate collections with new projected data. While a projection is rebuilding, new events received by the projection are held in memory by the projections, then processed once the _rebuild_ is complete. This allows for zero downtime, and a rolling rebuild in an eventually consistent manner.
- There can be many instances of databases with view cache data and many application instances that operate on the same commit store for scaling purposes. Read requirements are almost always greater than the write requirements. Read and write parts of the CQRS system can scale independently.
- A/B testing is possible with two sets of projections and UI logic, operating on one set of domain events (one commit store). This is important since we want early user feedback and quickly evolve our UI.
- Time travel is possible in ES system. If we want new or changed report, if we improve our machine learning algorithms its projection rebuilding time.
- No concurrency problems, domain commands are processed one at the time. State in the domain event commit store has actual consistency. View cache (projected data) is eventually consistent which is enough for client side validations, domain logic validates everything on the server side.
This list can be much longer but i hope this is enough to illustrate the power of projections in event sourced system.
I suggest watching some of Greg Young’ talks for anyone interested in easy ES/CQRS introduction:
Blog post is coming soon with details how we integrated Mantra and Space.
We would consider Space a set of libraries. The lower level space:base, space:messaging, and space:domain packages can easily be used standalone to achieve almost anything you desire.
@darkomijic many thanks the information. You have given us some light . The thing is that I really like both Mantra and Space. But I haven’t got enough time to experiment with both.
Right now I am transitioning from Blaze to React + Mantra + Meteor 1.3. Before moving any production apps there, I am working on simple apps for testing. So my next duty will be to thoroughly test Space
Do you think it is possible to start a project first with Mantra and then add Space progressively? Or it is better to start with Space from day 0?
I also see that some Space elements use Blaze, will you be moving to React as well?
We’re really focusing on the domain given the frontend has many opinions, and frankly there’s just less need for us in this area. A strategy we’re approaching right now is only use Space on the frontend to provide the messaging for CQRS in combination with your tech of choice, and Space to assist with DDD/ES on the backend. This allows for a decoupled domain, and highly optimised read collections for your frontend to consume.
As @sam would advocate, driving out the domain through specification is a very smart approach, so while technically there’s no problem with bringing Space in later, modelling your domain later is really doing things backwards
Check this out:
One of the goals with the project is to move the Space libraries to npm, making your domain even less coupled to Meteor. The only dependency blocking this right now is the check
package, however as @sashko indicated in the first Transmission podcast episode, there’s no technical limitation, and it would in fact be a good candidate to move to be an offering to the wider npm community.
- The nature of the beast, but a worthwhile investment that covers software development in general, not specific to Space or JS.
- There is a wealth of information and education already out there, so getting up to speed on these concepts is critical for the success of a Space domain implementation.
- If you’re comfortable with these concepts then you’re ready to get started.
- Read the expressive integration tests
- Review the example apps
- Ask questions in our Slack room
- Documentation and training material is high on our list of priorities now we have more clarity with our latest releases + MDG’s plans, and the mass adoption of npm client side solutions like React
Open to moving that out. But it’s one part I think needs to be maintained very carefully because it’s near the core of a lot of security critical code, both in Meteor itself and in Meteor apps.
Not sure if you have come across this: https://github.com/jedwards1211/npm-meteor-check/, which is a fork from the initial port from @raix - See discussion here: https://github.com/raix/npm-meteor-check/issues/1
Mantra and Space seem to be have different goals. In general I dislike it when people try to reinvent stuff like classes and modules on top of javascript, so I’m not a big fan of Space. Dependency injection can be quite useful though.
Mantra is more a set of guidelines, but you know, think for yourself and what you like. You can just read through what Mantra and Meteor guide advices and follow the guidelines you like and don’t follow the ones you don’t like. There’s no good or bad, there’s just what works for your application.
@darkomijic having a tutorial explaining how to built and integrate Event Sourcing and CQRS to a simple app such as the Space - Todos will be extremely useful.
I could not agree more. The referenced documentation is A little to verbose. There’s a lot to figure out.
@PolGuixe, @jitterbop: @sam and me have started working on a tutorial. We are creating a new sample application based on Cafe CQRS tutorial to illustrate Event Sourcing on real-world problem/domain and to showcase testing best practices. Stay tuned.