Fork me on GitHub

re-frame is, at the end of the day, a library for doing global event dispatch in a single process. if your backend doesn't handle much of that, e.g. is a web-api that talks to a database, or needs to distribute these messages in some way, then it won't be very useful for your backend


Hmm. I disagree. IMO, the client/server version of re-frame is some variation on CQRS.


The trick is to fully and deeply understand CQRS and then to back away slowly from the full complexity it could bring if you implemented CQRS/ES completely.


Find a simple version of it which honors the spirit of CQRS but which is as simple as you can make it.


But, I make no recommendations whatsoever in this area (other than to wave my hand weakly in a general direction) because I've only got a decade of experience in this stuff (only a few projects) which is not enough to have explored the solutions landscape ... I know what I know ... which is absolutely not enough. (In contrast, when it comes to pure GUI technologies I have 4 decades of experience and there ain't many solutions that I don't have experience with. So, I feel qualified to talk with some certainty about that space). I'd suggest that consultants like JUXT or Metosin would be great people to ask for advice - they get to start and observe many, many projects. Also, our apps involve a complicated SPAs but with simple server interactions. Other people's web apps will have quite different needs, particularly those that are simple, mostly a thin veneer over a remote database - that kind of a scenario leads you to quite different architectures. Also, our applications only service maybe 1000 users, so performance is never, ever an issue for us - we solve all performance problems with more hardware - and we hardly ever need to. If you have more users, and performance is an issue, your requirements might well lead you in quite different directions. Enough caveats? Having said that, we have evolved towards the following ... We use a simple version of CQRS (no ES) which relies on these backend components: 1. Postgress 2. An instance of Hasura (GraphQL) in front of Postgres 3. One or more servers which handle "effects" (We use Django to write these servers, but that's because of history. Could be Clojure. Or Go. Or whaatever) And it works like this: 1. To handle the "Q" part of CQRS, Hasura allows our ClojureScript clients to subscribe to data via GraphQL (or just query it once, when that is sufficient and realtime subscriptions are not needed). 2. To handle the "C" part of CQRS, Clients post "effects" as mutations back through Hasura and into a Postgres "effects table". By effects, I means for things like "send email" or "post confirmation to counterparty". Other parts of the system (the servers themselves) can also post to the effects table as well. This table represents a full audit trail of everything done. It also allows us to handle async operations which might fail and need to be retried. We mark effects as complete when they have been actioned. Clients can subscribe to effects, if that's important to them. 3. Hasura allows us to set up webhooks for the effects table (when new rows are added) which call out to the servers, getting them to action the effects. This means that our Clients do "more" than in a lot of other architecture. That was a deliberate choice. But some developers will not like that arrangement at all. It works well for us but, again, I stress that I'm not in any way making recommendations here, other than to say that re-frame is definitely CQRS in nature.

👏 16

BTW, I look forward to exploring crux as a back end at some point in the next year. But Hasura/Postgres has been a VERY good experience for us (simple/easy/performant/flexible).

👍 12
David Pham10:01:06

Thanks a lot for your insights @mikethompson