In a DDD CQRS API, is it preferable to have a separate DTO per query or per representation of a resource?

I am in the middle of starting up a new project and just wanted some reassurance as to which approach to DTO’s returned by the read-side was easier to maintain in a real world application with reasonable complexity.

I realize with a DTO per query, it would allow for a specific query’s response to diverge from the others more easily in the future. However, common properties between that query and other queries would require changes in multiple places (e.g. the same resource could have multiple queries in the form of GetById, GetAll, GetByStatus, GetBySomethingElse, etc.) and there is more repetition.

If a DTO is created per representation of a resource, a GetById might return a DetailedDto with many properties, while a GetAll might return a SummarizedDto with fewer properties. This would require less changes for common properties and diverging queries would just require a new version of the DTO to be created. The biggest disadvantage to this approach is that I’m terrible at naming classes and coming up with words, so “Detailed” + “Summarized” is the extent of my imagination.

I’m leaning towards refactoring my first attempt at writing this application from using the “DTO per query” to the “DTO per representation” approach. Are there any benefits to sticking with the “DTO per query” or is “DTO per representation” a good way to go?

Is it preferable to “compose” monadic functions or “chain” them?

To the best of my understanding Monads were created to allow for composing functions with those that had potential side-effects – loosely speaking.

For me composition implies code like so:

f(g(h(x))) 

In order to achieve this in a programming language one has to “line up the types” correctly, so that the output of h(x) is an input to g(...). Implying that such a function chaining would require all functions in the chain to work at the “monadic level of abstraction” for the types to line up correctly.

However, at my workplace (and some library code) I see a lot of code that looks more like “function chaining” like so:

h(x).flatMap(g).map(f) 

This is NOT function composition AFAIK and this probably makes code harder to read IMHO since there’s cognitive overload in understanding “type translation” with flatMap/map thrown into the mix. One has to mentally unravel the computations to see how they all “line up”.

What is the common convention in the FP-world? I had a few discussions with my peers and got extremely strong push back for the compositional style f(g(h(... – almost everyone preferred the “chaining style”. Is there a common “style guide” that’s advocated for something like this?

From my POV, I’ve been exposed to LISP/Scheme and f(g(h... isn’t really alien and is rather more clean and reads like a DSL. The chaining is rather hacky.

Question: Should functions work at the monadic level to allow for composition or is the suggestion to work at the level of the wrapped value?

Concrete example:

checkForBlanks(csvRows).flatMap(checkForUniqueIds).map(buildCache))  

vs

buildCache(checkForUniqueIds(checkForBlanks(csvRows))) 

Method signatures (Non-monadic):

def checkForBlanks(csvRecords: Vector[Record]): Either[InternalDomainError, Vector[Record]]  def checkForUniqueIds(csvRecords: Vector[Record]): Either[InternalDomainError, Vector[Record]]  def buildCache(csvRows: Vector[Record]): MyCache  

Method Signatures (Monadic):

def checkForBlanks(csvRecords: Vector[Record]): Either[InternalDomainError, Vector[Record]]  def checkForUniqueIds(data: Either[InternalDomainError, Vector[Record]]): Either[InternalDomainError, Vector[Record]]  def buildCache(data: Either[InternalDomainError, Vector[Record]]): MyCache  

Common points for pushback:

  • Composing forces reading right to left
  • Composing makes functions think of Monads and will clutter responsibility of handling wrappers
  • It’s easier if a function just works on the “actual value” vs. a monadic wrapper since it’s “easier to reason”
  • It’s way more flexible to “chain” than compose
  • If you really want to “compose” add additional methods that “call out” to pure methods and interally wrap monads – unnecessarily complicated so don’t do it: E.g.:
def uniq(data: Either[InternalDomainError, Vector[Record]]): Either[InternalDomainError, Vector[Record]] =            data.flatMap(checkForUniqueIds) 

From an FP-adherence and best practices POV what’s the recommendation on should one do this for readability/maintainability?

Fedora – Configuring as a Xen Host (EFI preferable)

I’ve got a new Fedora box that I’m setting up as a Xen host (Dom0), which is proving a little more difficult than expected.

First stop – install Xen via DNF and reboot. Find that the Xen boot option fails (lots of errors about multiboot). After a bit of googling I learn that this is because multiboot has been stripped out due to security concerns.[1]

Ok – well that’s annoying. Looks like I have two options [2]:

  • Manually reconfigure GRUB to use the older Chain Loader behaviour
  • Bypass GRUB and use Xen as the EFI bootloader

I’m going for option 2, since this seems like a cleaner solution and doesn’t require wrangling the layers of shell scripts that have built up around GRUB these days to make it do what I want.

I’ve gotten as far as creating an EFI boot option for Xen, but it appears to get silently skipped on start up. No errors, no useful output. I’m not sure what to check next.

What I’ve got so far:

EFI partition has EFI/xen with:

  • xen.efi (copy of EFI/fedora/xen-4.11.1.efi)
  • Copies of initramfs & vmlinuz from /boot
  • xen.cfg

xen.cfg text:

[global] default=fedora  [fedora] options= kernel=vmlinuz root=/dev/nvme0n1p1 rhgb LANG=en_GB.UTF-8 ramdisk=initramfs.img 

EFI option created using:

efibootmgr -c -L Xen -d /dev/sdc -p 1 -l \EFI\xen\xen.efi -c 

Target state here is: Machine booting with Xen and a Fedora Dom0. What should I check, or what should I try next?

[1] https://access.redhat.com/security/cve/cve-2015-5281

[2] https://wiki.xenproject.org/wiki/Xen_EFI