Good morning, Chris!

Thank you for the book!

After reading the latest chapter I have been thinking of one case.

Consider a banking transaction. Two-legged one, to simplify a little bit. There are two accounts and one transaction. What are aggregates (DDD) here? Obviously, we can't manipulate accounts separately, because the state can become inconsistent. So, an accounting transaction itself could be an aggregate, am I right? There are not so many events in the lifecycle of such aggregate.

But if we take an accounting transaction as the aggregate, there is another issue: how do we shard all the data? Ideally, all accounting transactions for a given account should occure in a single shard. This way we could extract all the account's transactions with one select for sure. But we can't partition transactions this way because of their sharing nature. If transactions are spread among several shards, we must query each and every shard to make sure that there are no missing transactions left when calculating an account's current state.

I feel, that here we should implement a multi-step workflow, where first accounting transactions are stored, and then from the flow of these transactions, the accounts' state is changed. Maybe, not a saga. Because after an accounting transaction is saved, there is no need to compensate. At least, within the borders of that transactions. But I'm afraid I'm missing something.

What would be a suitable approach in such situations?

Thank you!
Hello, Matt!

First of all, thanks for the great book!

As we all know, CoreOS team have issued a deprecation warning about Fleet (in README here: https://github.com/coreos/fleet ). They plan to swap it to Kubernetes. Hope, it would simplify deploing CoreOS/Kubernetes cluster.

Do You have any plans to update the book accordingly? Or, maybe, second edition covering CoreOS+Kubernetes?

Thank You!
Ilja Tollu
Hello, all!

I've tried to figure this question out for quite some time, but at last here it is.

If I understand the purpose of domain model file structure correctly, then each service serves some particular use case, maybe parametrized on types.

But suppose that several such services use some common parts. Say, I have the following formatter which is used converts media type objects (JSON, XML, ...) to domain model objects and back:
trait Formatter[MediaType, DomainType]{
    def read(source: MediaType): Valid[DomainType]

    def write(obj: DomainType): MediaType // Or maybe Valid[MediaType] to make it compose
}


Such a formatter is definitely not a service by itself. It is rather adapter and is used in all use cases involving, for example, REST controllers. So, it is used by the services, i.e. should be part of domain model.
In general, my question is not about adapters in particular, but about such abstract common parts, which are used throughout the domain algebra.

What are good ways to bring such abstracts into the physical structure of the domain model?

Thank you!
Hello, colleagues!

Let me suggest.

You mean, why can't we define behaviour as objects' (entities and values) methods rather than functions?

1. If you do that you supposedly are going to read some state and use some methods of
this
, not just method arguments.
This makes methods impure, so they can't be passed to higher order functions like
flatMap
and the like.
Also, you'll not be able to use function combinators
andThen
or
compose


2. Follows from the previous point: calling an object's method makes it execute immediately, so you can no more build computation, but rather you run a chain of evaluations. Besides, how'd you return something like
Either[Err, Obj]
, if you need to chain to your behaviour farther?

3. Also follows from the first point. All these Lenses, Monads, Applicatives et cetera address the problem of abstracting context from its content. You can write and test it once, or better take some ready solution like Scalaz and then use it many times within your domain. But if you don't separate behaviour from objects, you'll have to build this context logic back into your objects making them unmanageable.

4. Of course, you can couple object with behaviour as long as that is the object's exclusive behaviour, i.e. you don't need to reuse it, and if it makes code cleaner than decoupled version.

This is just my humble opinion.
I'm also waiting for Debasish to bring some light to this and sibling topics.

Best regards!
Ilja
Hello, colleagues!
The following use case is typical for REST service, I believe.
Consider a POST-controller: it parses JSON data into some Entity (case class) andThen persists it into repository.
It returns `Created` response on success, otherwise it can be `Bad request` (parsing failed) or `Internal Server Error` (db operation failed).
So, we design EntityService like this:
    // Source can be PlayFramework's JsValue 
    trait EntityService[Source] {
        def parse(src: Source): \/[Errors, Entity]
        def persist(entity: Entity, repo: Repo): EitherT[Future, Errors, Entity]
    }


How should I modify this code to make it compose? ParsingService needs nor Repo, neither Future (it is non-blocking). Persisting needs both. Does this mean that should wrap parsing result into Future or EitherT or Kleisli?

In more complex use cases we may have a need to compose further i.e. use Kleisli composition when it comes to futures and eithers. But I tried to keep it simple.

Thank you!
Thank You for great book!
As I am trying to implement this knowledge in REST-service, I feel myself a little bit messed about modularization.
One question is: where should I put Protocols (traits) and their implementations (traits with companion objects)? Should it be considered a service or some other part of domain? Then, if I get it correctly, I should import some protocol interpreter without protocol trait itself, right?

Best regards!
Ilja Tollu
Happy New Year, colleagues!

I've updated that Github project with new tag "fixed". It shows example config where third-party untyped library (Ramda, in this example) is imported into TypeScript code with ES6 "import" syntax and then loaded by SystemJS in browser.

An improvement would be to setup SystemJS bundling, but I'll wait 'till this topic is covered in this book.

Regards,
Ilja
Thank you for reply, Anton!

I've created a Github repo to demonstrate this issue: https://github.com/im-tollu/broken-import

There are two tags there: "works" and "broken".

I've put index.html into nested folder on purpose: it is useful to try project setup when html and app are situated in different folders. Also, when I launch index.html from IntelliJ IDEA (or WebStorm), it opens the app at some context path, i.e. not
http://localhost:63342/...
, but
http://localhost:63342/broken-import/...
It is useful to avoid hardcoding context path when an app may be deployed to different contexts.

Regards,
Ilja
Hello, All!

Not all libraries that we might want to use are typed. E.g. ramda or rx-dom. If we try to import them in typescript file compiler complains that there is no such module.

Furthermore, those libs do not get resolved correctly by SystemJS.

Are there any approaches to this problem?

Thank you!