{"id":2278,"date":"2018-08-14T22:34:16","date_gmt":"2018-08-14T21:34:16","guid":{"rendered":"https:\/\/www.entropywins.wtf\/blog\/?p=2278"},"modified":"2018-08-20T08:35:31","modified_gmt":"2018-08-20T07:35:31","slug":"bounded-contexts-in-the-wikimedia-fundraising-software","status":"publish","type":"post","link":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/","title":{"rendered":"Bounded Contexts in the Wikimedia Fundraising Software"},"content":{"rendered":"<p>In this follow-up to <a href=\"https:\/\/www.entropywins.wtf\/blog\/2016\/11\/24\/rewriting-the-wikimedia-deutschland-funrdraising\/\">rewriting the Wikimedia Deutschland fundraising<\/a> I tell the story of how we reorganized our codebases along the lines of the DDD strategic pattern Bounded Contexts.<\/p>\n<p>In 2016 the FUN team at <a href=\"https:\/\/wikimedia.de\/en\/\">Wikimedia Deutschland<\/a> rewrote the Wikimedia Deutschland fundraising application. This new codebase uses <a href=\"https:\/\/www.entropywins.wtf\/blog\/2016\/11\/24\/implementing-the-clean-architecture\/\">The Clean Architecture<\/a> and near the end of the rewrite got reorganized partially towards <a href=\"https:\/\/martinfowler.com\/bliki\/BoundedContext.html\">Bounded Contexts<\/a>. After adding many new features to the application in 2017, we reorganized further towards Bounded Contexts, this time also including our other fundraising applications. In this post I explain the questions we had and which decisions we ended up making. I also link to the relevant code so you have real world examples of using both The Clean Architecture and Bounded Contexts.<\/p>\n<p>This post is a good primer to my <a href=\"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/clean-architecture-bounded-contexts\/\">Clean Architecture + Bounded Contexts<\/a> post, which describes the structure and architecture rules we now have in detail.<\/p>\n<h2>Our initial rewrite<\/h2>\n<p>Back in 2014, we had two codebases, each in their own git repository and not using code from the other. The first one being a user facing PHP web-app that allows people to make donations and apply for memberships, called <a href=\"https:\/\/github.com\/wmde\/FundraisingFrontend\">FundraisingFrontend<\/a>. The &#8220;frontend&#8221; here stands for &#8220;user facing&#8221;. This is the application that we rewrote in 2016. The second codebase mainly contains the Fundraising Operations Center, a PHP web-app used by the fundraising staff to moderate and analyze donations and membership applications. This second codebase also contains some scripts to do exports of the data for communication with third-party systems.<\/p>\n<p>Both the FundraisingFrontend and Fundraising Operations Center (FOC) used the same MySQL database. They each accessed this database in their own way, using PDO, Doctrine or SQL directly. In 2015 we created a <a href=\"https:\/\/github.com\/wmde\/FundraisingStore\/\">Fundraising Store<\/a> component based on <a href=\"https:\/\/www.doctrine-project.org\/\">Doctrine<\/a>, to be used by both applications. Because we rewrote the FundraisingFrontend, all data access code there now uses this component. The FOC codebase we have been gradually migrating away from random SQL or PDO in its logic to also using this component, a process that is still ongoing.<\/p>\n<p>Hence as we started with our rewrite of the\u00a0FundraisingFrontend in 2016, we had 3 sets of code: FundraisingFrontend, FOC and Fundraising Store. After our rewrite the picture still looked largely the same. What we had done was turning FundraisingFrontend from a big ball of mud into a well designed application with proper architecture and separation of subdomains using Bounded Contexts. So while there where multiple components within the FundraisingFrontend, it was still all in one codebase \/ git repository. (Except for several small PHP libraries, but they are not relevant here.)<\/p>\n<h2>Need for reorganization<\/h2>\n<p>During 2017 we did a bunch of work on the FOC application and associated export script, all the while doing gradual refactoring towards sanity. While refactoring we found ourself implementing things such as a DonationRepository, things that already existed in the Bounded Contexts part of the FundraisingFrontend codebase. We realized that at least the subset of the FOC application that does moderation is part of the same subdomains that we created those Bounded Contexts for.<\/p>\n<p>The inability to use these Bounded Contexts in the FOC app was forcing us to do double work by creating a second implementation of perfectly good code we already had. This also forced us to pay a lot of extra attention to avoid inconsistencies.\u00a0 For instance, we ran into issues with the FOC app persisting Donations in a state deemed invalid by the donations Bounded Context.<\/p>\n<p>To address these issues we decided to share the Bounded Contexts that we created during the 2016 rewrite with all relevant applications.<\/p>\n<h2>Sharing our Bounded Contexts<\/h2>\n<p>We considered several approaches to sharing our Bounded Contexts between our applications. The first approach we considered was having a dedicated git repository per BC. To do this we would need to answer what exactly would go into this repository and what would stay behind. We where concerned that for many changes we&#8217;d need to touch both the BC git repo and the application git repo, which requires more work and coordination than being able to make a change in a single repository. This lead us to consider options such as putting all BCs together into a single repo, to minimize this cost, or to simply put all code (BCs and applications) into a single huge repository.<\/p>\n<p>We ended up going with one repo per BC, though started with a single BC to see how well this approach would work before committing to it. With this approach we still faced the question of what exactly should go into the BC repo. Should that just be the UseCases and their dependencies, or also the presentation layer code that uses the UseCases? We decided to leave the presentation layer code in the application repositories, to avoid extra (heavy) dependencies in the BC repo and because the UseCases provide a nice interface to the BC. Following this approach it is easy to tell if code belongs in the BC repo or not: if it binds to the domain model, it belongs in the BC repo.<\/p>\n<p>These are the Bounded Context git repositories:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/wmde\/fundraising-donations\">Fundraising Donations (Donation Context)<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/wmde\/fundraising-memberships\">Fundraising Memberships (Membership Context)<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/wmde\/fundraising-payments\">Fundraising Payments (Payment Context)<\/a><\/li>\n<\/ul>\n<p>The BCs still use the FundraisingStore component in their data access services. Since this is not visible from outside of the BC, we can easily refactor towards removing the FundraisingStore and having the data access mechanism of a BC be truly private to it (as it is supposed to be for BCs).<\/p>\n<p>The new BC repos allow us to continue gradual refactoring of the FOC and swap out legacy code with UseCases from the BCs. We can do so without duplicating what we already did and, thanks to the proper encapsulation, also without running into consistency issues.<\/p>\n<h2>Clean Architecture + Bounded Contexts<\/h2>\n<p>During our initial rewrite <a href=\"https:\/\/www.entropywins.wtf\/blog\/2016\/09\/09\/clean-architecture-diagram\/\">we created a diagram<\/a> to represent the favor of The Clean Architecture that we where using. For an updated version that depicts the structure of The Clean Architecture + Bounded Contexts and describes the rules of this architecture in detail, see my blog post <a href=\"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/clean-architecture-bounded-contexts\/\">The Clean Architecture + Bounded Contexts<\/a>.<\/p>\n<p><a href=\"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/clean-architecture-bounded-contexts\/\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"2303\" data-permalink=\"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/such-clean-diagram\/\" data-orig-file=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/Such-Clean-Diagram.png\" data-orig-size=\"1367,882\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Clean Architecture + Bounded Contexts\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/Such-Clean-Diagram.png\" class=\"alignnone wp-image-2303\" src=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/Such-Clean-Diagram.png\" alt=\"Diagram depicting Clean Architecture + Bounded Contexts\" width=\"850\" height=\"548\" \/><\/a><\/p>\n<blockquote class=\"twitter-tweet\" data-cards=\"hidden\" data-lang=\"en\">\n<p lang=\"en\" dir=\"ltr\">Bounded Contexts in the Wikimedia Fundraising Software  <a href=\"https:\/\/t.co\/AXAA7qh68B\">https:\/\/t.co\/AXAA7qh68B<\/a>  <a href=\"https:\/\/twitter.com\/hashtag\/CleanCode?src=hash&amp;ref_src=twsrc%5Etfw\">#CleanCode<\/a> <a href=\"https:\/\/twitter.com\/hashtag\/CleanArchitecture?src=hash&amp;ref_src=twsrc%5Etfw\">#CleanArchitecture<\/a> <a href=\"https:\/\/twitter.com\/hashtag\/DDDesign?src=hash&amp;ref_src=twsrc%5Etfw\">#DDDesign<\/a> <a href=\"https:\/\/twitter.com\/hashtag\/BoundedContexts?src=hash&amp;ref_src=twsrc%5Etfw\">#BoundedContexts<\/a><\/p>\n<p>&mdash; Such Much Such (@JeroenDeDauw) <a href=\"https:\/\/twitter.com\/JeroenDeDauw\/status\/1031435162746347520?ref_src=twsrc%5Etfw\">August 20, 2018<\/a><\/p><\/blockquote>\n<p><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this follow-up to rewriting the Wikimedia Deutschland fundraising I tell the story of how we reorganized our codebases along&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[7],"tags":[426,429,328,405,437,332,197,215,430,336],"class_list":["post-2278","post","type-post","status-publish","format-standard","hentry","category-programming","tag-bounded-contexts","tag-clean-architecture","tag-clean-code","tag-domain-driven-design","tag-fundraising","tag-legacy-code","tag-planet-wikimedia","tag-refactoring","tag-software-architecture","tag-wmde"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Bounded Contexts in the Wikimedia Fundraising Software - Blog of Jeroen De Dauw<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Bounded Contexts in the Wikimedia Fundraising Software - Blog of Jeroen De Dauw\" \/>\n<meta property=\"og:description\" content=\"In this follow-up to rewriting the Wikimedia Deutschland fundraising I tell the story of how we reorganized our codebases along&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog of Jeroen De Dauw\" \/>\n<meta property=\"article:published_time\" content=\"2018-08-14T21:34:16+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-08-20T07:35:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/Such-Clean-Diagram.png\" \/>\n<meta name=\"author\" content=\"Jeroen\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/JeroenDeDauw\" \/>\n<meta name=\"twitter:site\" content=\"@JeroenDeDauw\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeroen\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/\"},\"author\":{\"name\":\"Jeroen\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"headline\":\"Bounded Contexts in the Wikimedia Fundraising Software\",\"datePublished\":\"2018-08-14T21:34:16+00:00\",\"dateModified\":\"2018-08-20T07:35:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/\"},\"wordCount\":1037,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"image\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/08\\\/Such-Clean-Diagram.png\",\"keywords\":[\"Bounded Contexts\",\"Clean Architecture\",\"Clean Code\",\"Domain Driven Design\",\"Fundraising\",\"Legacy code\",\"Planet Wikimedia\",\"Refactoring\",\"Software Architecture\",\"WMDE\"],\"articleSection\":[\"Programming\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/\",\"url\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/\",\"name\":\"Bounded Contexts in the Wikimedia Fundraising Software - Blog of Jeroen De Dauw\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/08\\\/Such-Clean-Diagram.png\",\"datePublished\":\"2018-08-14T21:34:16+00:00\",\"dateModified\":\"2018-08-20T07:35:31+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/08\\\/Such-Clean-Diagram.png\",\"contentUrl\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/08\\\/Such-Clean-Diagram.png\",\"width\":1367,\"height\":882,\"caption\":\"Diagram depicting Clean Architecture + Bounded Contexts\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2018\\\/08\\\/14\\\/bounded-contexts-in-the-wikimedia-fundraising-software\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Bounded Contexts in the Wikimedia Fundraising Software\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/\",\"name\":\"Entropy Wins\",\"description\":\"A blog on Software Architecture, Design and Craftsmanship\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\",\"name\":\"Jeroen\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\",\"caption\":\"Jeroen\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\"},\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/jeroendedauw\\\/\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/JeroenDeDauw\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Bounded Contexts in the Wikimedia Fundraising Software - Blog of Jeroen De Dauw","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/","og_locale":"en_US","og_type":"article","og_title":"Bounded Contexts in the Wikimedia Fundraising Software - Blog of Jeroen De Dauw","og_description":"In this follow-up to rewriting the Wikimedia Deutschland fundraising I tell the story of how we reorganized our codebases along&hellip;","og_url":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/","og_site_name":"Blog of Jeroen De Dauw","article_published_time":"2018-08-14T21:34:16+00:00","article_modified_time":"2018-08-20T07:35:31+00:00","og_image":[{"url":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/Such-Clean-Diagram.png","type":"","width":"","height":""}],"author":"Jeroen","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/JeroenDeDauw","twitter_site":"@JeroenDeDauw","twitter_misc":{"Written by":"Jeroen","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/#article","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/"},"author":{"name":"Jeroen","@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"headline":"Bounded Contexts in the Wikimedia Fundraising Software","datePublished":"2018-08-14T21:34:16+00:00","dateModified":"2018-08-20T07:35:31+00:00","mainEntityOfPage":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/"},"wordCount":1037,"commentCount":3,"publisher":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"image":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/#primaryimage"},"thumbnailUrl":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/Such-Clean-Diagram.png","keywords":["Bounded Contexts","Clean Architecture","Clean Code","Domain Driven Design","Fundraising","Legacy code","Planet Wikimedia","Refactoring","Software Architecture","WMDE"],"articleSection":["Programming"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/","url":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/","name":"Bounded Contexts in the Wikimedia Fundraising Software - Blog of Jeroen De Dauw","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/#primaryimage"},"image":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/#primaryimage"},"thumbnailUrl":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/Such-Clean-Diagram.png","datePublished":"2018-08-14T21:34:16+00:00","dateModified":"2018-08-20T07:35:31+00:00","breadcrumb":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/#primaryimage","url":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/Such-Clean-Diagram.png","contentUrl":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/Such-Clean-Diagram.png","width":1367,"height":882,"caption":"Diagram depicting Clean Architecture + Bounded Contexts"},{"@type":"BreadcrumbList","@id":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/bounded-contexts-in-the-wikimedia-fundraising-software\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.entropywins.wtf\/blog\/"},{"@type":"ListItem","position":2,"name":"Bounded Contexts in the Wikimedia Fundraising Software"}]},{"@type":"WebSite","@id":"https:\/\/www.entropywins.wtf\/blog\/#website","url":"https:\/\/www.entropywins.wtf\/blog\/","name":"Entropy Wins","description":"A blog on Software Architecture, Design and Craftsmanship","publisher":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.entropywins.wtf\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7","name":"Jeroen","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g","caption":"Jeroen"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g"},"sameAs":["https:\/\/www.linkedin.com\/in\/jeroendedauw\/","https:\/\/x.com\/https:\/\/twitter.com\/JeroenDeDauw"]}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p74TBF-AK","jetpack-related-posts":[{"id":2358,"url":"https:\/\/www.entropywins.wtf\/blog\/2018\/09\/09\/clean-architecture-bounded-contexts-diagram\/","url_meta":{"origin":2278,"position":0},"title":"Clean Architecture + Bounded Contexts diagram","author":"Jeroen","date":"2018-09-09","format":false,"excerpt":"I\u2019m happy to release a two Clean Architecture + Bounded Contexts diagrams into the public domain (CC0 1.0). I created these diagrams for Wikimedia Deutchland with the help of Jan Dittrich, Charlie Kritschmar and Hanna Petruschat. They represent the architecture of our fundraising codebase. I explain the rules of this\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/09\/FunArchitecture.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/09\/FunArchitecture.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/09\/FunArchitecture.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/09\/FunArchitecture.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/09\/FunArchitecture.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":2210,"url":"https:\/\/www.entropywins.wtf\/blog\/2018\/08\/14\/clean-architecture-bounded-contexts\/","url_meta":{"origin":2278,"position":1},"title":"Clean Architecture + Bounded Contexts","author":"Jeroen","date":"2018-08-14","format":false,"excerpt":"In this follow-up to Implementing the Clean Architecture I introduce you to a combination of The Clean Architecture and the strategic DDD pattern known as Bounded Contexts. At Wikimedia Deutschland we use this combination of The Clean Architecture and Bounded Contexts for our fundraising applications. In this post I describe\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/CleanArchitecture_DomainDrivenDesign.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/CleanArchitecture_DomainDrivenDesign.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/CleanArchitecture_DomainDrivenDesign.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/CleanArchitecture_DomainDrivenDesign.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2018\/08\/CleanArchitecture_DomainDrivenDesign.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":1807,"url":"https:\/\/www.entropywins.wtf\/blog\/2016\/09\/09\/clean-architecture-diagram\/","url_meta":{"origin":2278,"position":2},"title":"Clean Architecture diagrams","author":"Jeroen","date":"2016-09-09","format":false,"excerpt":"I'm happy to release a few Clean Architecture related diagrams into the public domain (CC0 1.0). Update 2018-9-9: new diagrams featuring Bounded Contexsts are now available! These diagrams where created at Wikimedia Deutchland by Jan Dittrich, Charlie Kritschmar and myself for an upcoming presentation I'm doing on the Clean Architecture.\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/09\/Clean_Architecture_core.svg_.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/09\/Clean_Architecture_core.svg_.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/09\/Clean_Architecture_core.svg_.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1846,"url":"https:\/\/www.entropywins.wtf\/blog\/2016\/11\/24\/implementing-the-clean-architecture\/","url_meta":{"origin":2278,"position":3},"title":"Implementing the Clean Architecture","author":"Jeroen","date":"2016-11-24","format":false,"excerpt":"Both Domain Driven Design and architectures such as the Clean Architecture and Hexagonal are often talked about. It's hard to go to a conference on software development and not run into one of these topics. However it can be challenging to find good real-world examples. In this blog post I'll\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/11\/CleanArchitecture.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/11\/CleanArchitecture.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/11\/CleanArchitecture.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2016\/11\/CleanArchitecture.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":2044,"url":"https:\/\/www.entropywins.wtf\/blog\/2017\/05\/24\/generic-entity-handling-code\/","url_meta":{"origin":2278,"position":4},"title":"Generic Entity handling code","author":"Jeroen","date":"2017-05-24","format":false,"excerpt":"In this blog post I outline my thinking on sharing code that deals with different types of Entities in your domain. We\u2019ll cover what Entities are, code reuse strategies, pitfalls such as Shotgun Surgery and Anemic Domain Models and finally Bounded Contexts. Why I wrote this post I work at\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1792,"url":"https:\/\/www.entropywins.wtf\/blog\/2016\/07\/14\/notes-implementing-ddd-chapter-2\/","url_meta":{"origin":2278,"position":5},"title":"Notes: Implementing DDD, chapter 2","author":"Jeroen","date":"2016-07-14","format":false,"excerpt":"Notes from Implementing Domain Driven Design, chapter 2: Domains, Subdomains and Bounded Contexts (p58 and later only) User interface and service orientated endpoints are within the context boundary Domain concepts in the UI form the Smart UI Anti-Pattern A database schema is part of the context if it was created\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/2278","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/comments?post=2278"}],"version-history":[{"count":9,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/2278\/revisions"}],"predecessor-version":[{"id":2322,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/2278\/revisions\/2322"}],"wp:attachment":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/media?parent=2278"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/categories?post=2278"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/tags?post=2278"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}