BFF and CQRS
My idol Sam Newman goes all in for BFF pattern, explained here and also better in his book and warns for the developer cognitive overhead of CQRS. I've heard the same about Event Sourcing, on Event Driven architecture talks, do it only when necessary.
I agree it's more complicated but it also tears apart everything so you can separate view concerns from write concerns, and having a very good DDD model, especially the "write" part, not having to deal with view concerns in many places.
Now my doubt comes that it looks like BFF, a pattern that uses a dedicated backend for a frontend client, kind of solves the same issue that CQRS is solving with the projections. The CQRS version as explained in this book and this other book. Basically the way I am doing it in the examples here with my Rust service.
Sam Newman argues that CQRS is an internal concern of a single microservice, and I agree.
But how easy it is to add user data on a projection that has a list of products, all sold by different users, you can just add the user information in the projection! no need to make a thousand calls, either from the final client -nope- but not even for the BFF, for each item in the list, to fetch the user information. We have it ready with a single call!
Now I think how would be the final solution to mix both worlds.
Working with CQRS makes you realize that all the projections, that are a result of event handlers could be deployed independently, and have even a smaller unit of a "service".
Sam Newman also says to avoid code deduplication on several BFF, one can add a new microservice that has the same functionality for both - he warns that it should match business concerns- you can argue that the need of viewing some data is acally a business concern-. Anyway, if you take the projection as a "stand-alone service" be it or not, still if it belongs to the main service, but from the BFF point of view it thinks it's making the call to that new service called "product list".
It feels that viewing concerns, all of those projections could be independent things, so eventually satellites of the main service. And indeed having them in the BE code feels like a lot of hustle, so why do it? well, it's still way faster to have a single projection a single call even if it's from BFF than many. And also those projections can be used somewhere.
But this helped me realize that it might be a good idea to treat the viewing part, the querying concerns, like even another microservice. Imagine the entanglement if in that product list, we add, let's say, inventory items left from another service, and keep adding things, this work of aggregation - hey Ethan Garofolo calls the handlers aggregators- might be worth treating it separately, maybe not physically but mentally in our minds.
And the other thing is that I am leaning more toward the view that aggregation of views among services might not be a part of CQRS, and might be more of BFF, or of a specialized independent service that keeps updated a projection if necessary, but that probably doesn't belong to any bounded context of any specific service, but on a shared space.
I think that's how my vision of CQRS and BFF coexist. And that's how I might have been -very slightly- wrong again. But, hey, that's how we get better.
Subscribe to my newsletter
Read articles from Francesc Travesa directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by