emacsway-log: Software Design, Clean Architecture, DDD, Microservice Architecture, Distributed Systems, XP, Agile, etc. – Telegram
emacsway-log: Software Design, Clean Architecture, DDD, Microservice Architecture, Distributed Systems, XP, Agile, etc.
3.48K subscribers
119 photos
15 videos
22 files
1.14K links
Software Design, Clean Architecture, DDD, Microservice Architecture, Distributed Systems, Extreme Programming, SDLC, Agile, etc.

Chat: https://news.1rj.ru/str/emacsway_chat

Persistence: https://dckms.github.io/system-architecture/
Download Telegram
emacsway-log: Software Design, Clean Architecture, DDD, Microservice Architecture, Distributed Systems, XP, Agile, etc.
Хорошая статья про CQRS: "Types of CQRS" by Vladimir Khorikov - https://enterprisecraftsmanship.com/posts/types-of-cqrs/ Обратите внимание на комментарии внизу статьи - ее прорецензировал собственноручно Greg Young - автор термина CQRS. #DDD #Microservices…
Вернемся к вопросу о возврате ID созданного ресурса в ответ на POST запрос REST-API. Как говорилось ранее ( https://news.1rj.ru/str/emacsway_log/282 ), RFC-7231 требует, чтобы REST API вернул идентификатор созданного ресурса в ответ на HTTP POST запрос.

Какие вообще есть альтернативы?

📝 "If the data is needed by the client as soon as it is submitted, it is there – on the client that submitted it. No need to poll the query side. The only thing that might not have been there is an ID from the database – which is easily solved with client-generated GUIDs instead of database-generated IDs."
- "Clarified CQRS" comment 68 of Udi Dahan
http://udidahan.com/2009/12/09/clarified-cqrs/#comment-5118

Идентификатор может быть сгенерирован на стороне клиентского приложения, используя UUID ( https://en.wikipedia.org/wiki/Universally_unique_identifier ), Hi/Lo algorithm ( https://en.wikipedia.org/wiki/Hi/Lo_algorithm ) и т.п. После этого, ресурс может быть создан посредством PUT Request Method:

📝 "The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload. <...> If the target resource does not have a current representation and the PUT successfully creates one, then the origin server MUST inform the user agent by sending a 201 (Created) response."
- "Section 4.3.4. PUT of RFC-7231"
https://tools.ietf.org/html/rfc7231#section-4.3.4

Другим вариантом, как говорилось ранее ( https://news.1rj.ru/str/emacsway_log/284 ), может быть "Asynchronous Request-Reply pattern" ( https://docs.microsoft.com/en-us/azure/architecture/patterns/async-request-reply ), использующий 202 Response Status Code ( https://tools.ietf.org/html/rfc7231#section-6.3.3 ).

Но действительно ли нам нужно получать идентификатор в ответ на команду? Часто такая потребность возникает просто из-за недостаточного понимания тех выгод, которые предоставляет CQS и Referential Transparency - однонаправленный поток изменений и единственный источник истины.

#DDD #Microservices #SoftwareDesign #SoftwareArchitecture #FunctionalProgramming #OOP
emacsway-log: Software Design, Clean Architecture, DDD, Microservice Architecture, Distributed Systems, XP, Agile, etc.
Вернемся к вопросу о возврате ID созданного ресурса в ответ на POST запрос REST-API. Как говорилось ранее ( https://news.1rj.ru/str/emacsway_log/282 ), RFC-7231 требует, чтобы REST API вернул идентификатор созданного ресурса в ответ на HTTP POST запрос. Какие вообще…
Referential Transparency означает, что вызов функции можно многократно повторять без какого-либо ущерба, и она всегда будет возвращать один и тот же результат.

Более того, - возникает возможность легко управлять потоком изменений, сделав его однонаправленным, и сформировав единственный источник истины (single source of truth - один из ключевых принципов Redux https://redux.js.org/understanding/thinking-in-redux/three-principles , который следует принципам CQRS https://redux.js.org/understanding/thinking-in-redux/motivation ). Это существенно облегчает создание сложных приложений, используя Task Based UI, позволяет легко организовать репликацию и кэширование, устранить задержки. Подробнее эти вопросы хорошо раскрывает Udi Dahan в монументальной статье "Clarified CQRS":
http://udidahan.com/2009/12/09/clarified-cqrs/

Статья доступна для скачивания в формате pdf:
https://udidahan.com/wp-content/uploads/Clarified_CQRS.pdf

Представьте, что пользователь добавил в корзину последний товар, используя совмещенную операцию Команды и Запроса. В ответ на Команду, сервер сообщил, что товар снят с продажи. Клиентское приложение пользователя обновило свое состояние, и заблокировало в UI возможность заказать уже недоступный товар.

Я намеренно примитивизирую ситуацию - на самом деле она гораздо более сложнее в распределенных системах:
- https://youtu.be/fWU8ZK0Dmxs
- хороший пример с overbooking в книге https://martinfowler.com/books/nosql.html

Проблема в том, что между пользователем и сервером существует двунаправленный поток изменений, который недоступен остальным пользователям, так как операция модификации и чтения данных совмещена.

Другой пользователь, для которого источником истины является локальное состояние его клиентского приложения, ничего не знает о том, что товар уже недоступен, пытается его заказать, но, вместо подтверждения заказа, получает сообщение о недоступности товара.

Сюда можно добавить еще время, требуемое на обновление реплик чтения.

📝 "Staleness refers to the fact that in a collaborative environment, once data has been shown to a user, that same data may have been changed by another actor – it is stale. Almost any system which makes use of a cache is serving stale data – often for performance reasons. What this means is that we cannot entirely trust our users decisions, as they could have been made based on out-of-date information."
- "Clarified CQRS" by Udi Dahan
https://udidahan.com/2009/12/09/clarified-cqrs/

Отделение Команд от Запросов позволяет организовать однонаправленный поток изменений, и тогда оба пользователя одновременно получат сообщение о событии, что последний товар закончился.
https://udidahan.com/wp-content/uploads/cqrs.png

📝 "After the command-processing autonomous component has decided to accept a command, modifying its persistent store as needed, it publishes an event notifying the world about it."
- "Clarified CQRS" by Udi Dahan
https://udidahan.com/2009/12/09/clarified-cqrs/

📝 "CQRS is about coming up with an appropriate architecture for multi-user collaborative applications. It explicitly takes into account factors like data staleness and volatility and exploits those characteristics for creating simpler and more scalable constructs."
- "Clarified CQRS" by Udi Dahan
https://udidahan.com/2009/12/09/clarified-cqrs/

#DDD #Microservices #SoftwareDesign #SoftwareArchitecture #FunctionalProgramming #OOP
emacsway-log: Software Design, Clean Architecture, DDD, Microservice Architecture, Distributed Systems, XP, Agile, etc.
https://udidahan.com/wp-content/uploads/cqrs.png
Теперь, понимая важность однонаправленного потока изменений в условиях collaborative evironment, нам становится легче понять разницу между abstract side effect и concrete side effect.

В этом видео Udi Dahan использовал термин sandbox:
https://youtu.be/fWU8ZK0Dmxs

Часто ресурс начинает создаваться как черновик. Он не доступен никому через публичный интерфейс, кроме его автора. Никто не должен знать о его существовании, кроме его автора. И если мы нарушим здесь CQS, то никто этого не заметит. На ресурс распространяется concrete side effect:
- https://news.1rj.ru/str/emacsway_log/278
- https://news.1rj.ru/str/emacsway_log/283

Другое дело, когда мы должны опубликовать этот ресурс - тогда он должен появиться у всех, кто просматривает коллекцию, содержащую опубликованный ресурс (если, разумеется, это имеет ценность с точки зрения предметной области), а не только инициатор публикации. И все пользователи, включая автора, должны получить уведомление о публикации ресурса, через единый однонаправленный канал потока изменений.

Такой же вывод возникает и из принципа функции-конструктора: до тех пор, пока ресурс не принадлежит ни к одной из публичных коллекций, доступной остальным пользователям, side effect не имеет последствий:
- https://news.1rj.ru/str/emacsway_log/281

Но когда коллекция изменилась, то все пользователи, просматривающие эту коллекцию, должны быть уведомлены единовременно.

#DDD #Microservices #SoftwareDesign #SoftwareArchitecture #FunctionalProgramming #OOP
emacsway-log: Software Design, Clean Architecture, DDD, Microservice Architecture, Distributed Systems, XP, Agile, etc.
Теперь, понимая важность однонаправленного потока изменений в условиях collaborative evironment, нам становится легче понять разницу между abstract side effect и concrete side effect. В этом видео Udi Dahan использовал термин sandbox: https://youtu.be/fWU8ZK0Dmxs…
Ответ Jimmy Bogard по поводу того, может ли CQRS-Команда возвращать результат:

📝 "It might seem rather strange that commands always have a result, but it’s much, much easier to deal with side effects of commands through return parameters than through some other means (global registry, static field, re-querying some object, collecting parameter, etc.). For commands that create an item, I usually want to redirect to a screen showing that item, very easily accomplished when I can get the created item and as for its ID.

This is a bit controversial, but don’t frankly care, as it’s the simplest thing that could possibly work. If I want to have a command that returns Void, I could steal a page from F# and have a Command base class that returns a Unit type:"
- "Put your controllers on a diet: POSTs and commands" by Jimmy Bogard
https://lostechies.com/jimmybogard/2013/12/19/put-your-controllers-on-a-diet-posts-and-commands/

Обратите внимание, в последнем предложении он говорит о том, как вернуть и результат, и ошибку одновременно. Именно об этом шла речь здесь: https://news.1rj.ru/str/emacsway_log/279

Причины такого решения он раскрывает в другой своей статье:

📝 "Myth #2 – CQRS requires an eventual consistent read store

No, it does not. You can make your read store immediately consistent. That is, your read store can be updated when your command side succeeds (in the same transaction).

For many legacy/existing apps, transitioning to eventually consistent read stores will either force you to go through bogus hoops of mimicking synchronous calls. Users will bang down on your door with pitchforks and torches if you try and transition to an asynchronous model if you don’t change their business process first.

Instead, you can start with immediate consistency and transition where and when it’s needed. Unless a user expects a confirmation page, making every command page have a series of confirmations of “your request was received” is going to annoy the snot out of your users.

Myth #3 – CQRS requires a bus/queues/asynchronous messaging

See above myth. Nothing about CQRS says “thou shalt use NServiceBus”. It’s just not there. You’re merely separating infrastructure between handling commands and queries, but the how is quite varied. Don’t start with a bus until you prove you need eventual consistency.

Consistency models are a business decision because it directly impacts user experience. An eventually consistent model requires a different user experience than an immediate one, and this is not something you can just “slip in” to your users, or try to emulate. If you’re attempting to emulate immediate consistency in an eventually consistent model, you’re doing something wrong.
- “Busting some CQRS myths” by Jimmy Bogard
https://lostechies.com/jimmybogard/2012/08/22/busting-some-cqrs-myths/

Что он также подтверждает своим комментарием к этой статье:

📝 "Scaling and CQRS are orthogonal, it’s highly contextual and certainly doesn’t require async."
- "Busting some CQRS myths" by Jimmy Bogard
https://lostechies.com/jimmybogard/2012/08/22/busting-some-cqrs-myths/#comment-3422377189

Итак, ответ прост - если вы не используете асинхронное исполнение Команды посредством инфраструктуры (Command Bus), то ничто не препятствует вам получить идентификатор вновь созданной записи БД в возвращаемом командой результате, и реализацию можно существенно упростить. Впрочем, возвратить результат можно даже используя Command Bus, но тут вопрос к потреблению ресурсов (все зависит от конкретного случая).

Вопрос не в том, возвращает ли команда реультат (при этом нужно отличать результат от служебной информации, например, от успешности валидации и принятия команды), а в том, можно ли получить информацию о ресурсе без abstract side effect, т.е. смогут ли другие клиенты получить ту же информацию, если она им нужна.

#DDD #Microservices #SoftwareDesign #SoftwareArchitecture #FunctionalProgramming #OOP
1
Случайно наткнулся на паттерны DDD, выраженные в ArchiMate:
- https://github.com/wilmerkrisp/patterns/tree/master/domain%20driven%20design%20patterns

Поскольку Event Storming - это средство исследования домена, а не документирования, то "C.1.10 Business Process Cooperation Viewpoint" может пригодиться, чтобы задокументировать результат сессии Event Storming:
- https://pubs.opengroup.org/architecture/archimate31-doc/apdxc.html#_Toc10045506

Если вы никогда не использовали ArchiMate, то вряд ли эта ссылка будет для вас сильно информативной. В таком случае лучше скачать Archi® modelling toolkit ( https://www.archimatetool.com/ ) и переключить ViewPoint на Business Process Cooperation Viewpoint. Оно того стоит. Шпаргалка по ArchiMate: https://publications.opengroup.org/n190

Ранее уже говорилось, что и сам Event Storming в чистом виде можно рисовать в ArchiMate:
https://news.1rj.ru/str/emacsway_log/253

#DDD #SoftwareDesign #SoftwareArchitecture #ArchiMate #EventStorming
Мы в этом канале уже разобрали две большие темы:
- Проблема конкурирующих подписчиков и гонка событий: https://news.1rj.ru/str/emacsway_log/57
- CQRS/CQS и возврат результата командой https://news.1rj.ru/str/emacsway_log/276

Попутно было еще несколько заслуживающих внимания дискуссий в чате канала.

Наверное, все уже отдохнули от "тяжелых" тем, и можно браться за следующую. В последнее время часто вспоминается вопрос Monolith First vs. Microservices First в разных чатах, но при этом упускается один важный, я бы даже сказал - ключевой, момент, на который я хотел бы обратить внимание.

Если кто с этими терминами не знаком, то:
- Monolith First https://martinfowler.com/bliki/MonolithFirst.html
- Microservices First https://martinfowler.com/articles/dont-start-monolith.html

Но прежде чем мы погрузимся в эту тему, я хотел бы, чтобы каждый хорошо осознавал разницу между Microservice и Bounded Context (BC). Это важно, потому что границей автономности команды разработчиков является все-таки BC, а значит, микросервисы способствуют достижению автономности не прямо, а косвенно.

С подачи некоторых авторов одно время бытовало мнение, будто Microservice == BC. Некоторые из этих авторов сегодня уже пересмотрели свою точку зрения, и произошла определенная эволюция архитектурных знаний в этой области.

Лучшие, на мой взгляд, статьи, поясняющие разницу между Microservice и BC - это:

- “Bounded Contexts are NOT Microservices” by Vladik Khononov
https://vladikk.com/2018/01/21/bounded-contexts-vs-microservices/

- “Tackling Complexity in Microservices” by Vladik Khononov
https://vladikk.com/2018/02/28/microservices/

- “DDDDD: Bounded Contexts, Microservices, and Everything In Between” by Vladik Khononov
https://youtu.be/Z0RgR9xIQE4

- “Using domain analysis to model microservices“
https://docs.microsoft.com/en-us/azure/architecture/microservices/model/domain-analysis

- “Identifying microservice boundaries“
https://docs.microsoft.com/en-us/azure/architecture/microservices/model/microservice-boundaries

- “Reactive Microservices” by Vaughn Vernon
https://kalele.io/reactive-microservices/

- “Microservices and [Micro]services” by Vaughn Vernon
https://kalele.io/microservices-and-microservices/

#DDD #Microservice #SoftwareArchitecture
С Новым Годом! Ярких побед и высоких достижений в Новом Году! Пусть все задуманное осуществится! Здоровья, благополучия и успехов!)
☃️🥳🍾🎆🎇🎉🎄🎅❄️
"Architecture Ownership Patterns For Team Topologies. Part 1: A Business Architecture Model" by Nick Tune
- https://medium.com/nick-tune-tech-strategy-blog/team-responsibility-ownership-patterns-part-1-a-business-architecture-model-63597c4e60e1

"Architecture Ownership Patterns for Team Topologies. Part 2: Single Team Patterns" by Nick Tune
- https://medium.com/nick-tune-tech-strategy-blog/architecture-ownership-patterns-for-team-topologies-part-2-single-team-patterns-943d31854285

"Architecture Ownership Patterns for Team Topologies. Part 3: Multi-Team Patterns" by Nick Tune
https://medium.com/nick-tune-tech-strategy-blog/architecture-ownership-patterns-for-team-topologies-part-3-multi-team-patterns-eecc146ddb28

Цикл статей о том, как выравнивать команды и компоненты системы. Полезна всем, кто распределяет зоны ответственностей команд.

#DDD #Microservices #SoftwareArchitecture
​​ Breaking news!

#ruby 3.0.0 Released!

Ruby 3.0.0 covers those goals by:
- Performance: MJIT
- Concurrency: Ractor and Fiber Scheduler
- Typing (Static Analysis): RBS, TypeProf

https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/
Forwarded from Никита Соболев
Now Ruby has built-in actor model and jit.

Python is way behind all modern noscripting languages 😞