dockerfile/examples/omnivore/content-fetch/readabilityjs/test/test-pages/medium/source.html

1512 lines
319 KiB
HTML
Raw Permalink Normal View History

2024-03-15 14:52:38 +08:00
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta data-rh="true" charset="utf-8" />
<script async="async" src="https://cdn.branch.io/branch-latest.min.js"></script>
<script async="async" src="https://www.google-analytics.com/analytics.js"></script>
<script defer="defer" src="https://cdn.optimizely.com/js/16180790160.js"></script>
<title>
Building Domain Driven Microservices | by Chandra Ramalingam | Walmart Global Tech Blog | Medium
</title>
<meta data-rh="true" name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1" />
<meta data-rh="true" name="theme-color" content="#000000" />
<meta data-rh="true" name="twitter:app:name:iphone" content="Medium" />
<meta data-rh="true" name="twitter:app:id:iphone" content="828256236" />
<meta data-rh="true" property="al:ios:app_name" content="Medium" />
<meta data-rh="true" property="al:ios:app_store_id" content="828256236" />
<meta data-rh="true" property="al:android:package" content="com.medium.reader" />
<meta data-rh="true" property="fb:app_id" content="542599432471018" />
<meta data-rh="true" property="og:site_name" content="Medium" />
<meta data-rh="true" property="og:type" content="article" />
<meta data-rh="true" property="article:published_time" content="2020-08-19T18:48:52.064Z" />
<meta data-rh="true" name="title" content="Building Domain Driven Microservices | by Chandra Ramalingam | Walmart Global Tech Blog | Medium" />
<meta data-rh="true" property="og:title" content="Building Domain Driven Microservices" />
<meta data-rh="true" property="twitter:title" content="Building Domain Driven Microservices" />
<meta data-rh="true" name="twitter:site" content="@walmartlabs" />
<meta data-rh="true" name="twitter:app:url:iphone" content="medium://p/af688aa1b1b8" />
<meta data-rh="true" property="al:android:url" content="medium://p/af688aa1b1b8" />
<meta data-rh="true" property="al:ios:url" content="medium://p/af688aa1b1b8" />
<meta data-rh="true" property="al:android:app_name" content="Medium" />
<meta data-rh="true" name="description" content="The term micro in Microservices, though indicative of the size of a service, is not the only criteria that make an application a Microservice. When teams move to a microservices-based architecture…" />
<meta data-rh="true" property="og:description" content="Microservicesa definition" />
<meta data-rh="true" property="twitter:description" content="Microservicesa definition" />
<meta data-rh="true" property="og:url" content="https://medium.com/walmartglobaltech/building-domain-driven-microservices-af688aa1b1b8" />
<meta data-rh="true" property="al:web:url" content="https://medium.com/walmartglobaltech/building-domain-driven-microservices-af688aa1b1b8" />
<meta data-rh="true" property="og:image" content="https://miro.medium.com/max/1200/1*8xaltkmBH_FInTZe8nH1bQ.jpeg" />
<meta data-rh="true" name="twitter:image:src" content="https://miro.medium.com/max/1200/1*8xaltkmBH_FInTZe8nH1bQ.jpeg" />
<meta data-rh="true" name="twitter:card" content="summary_large_image" />
<meta data-rh="true" property="article:author" content="https://medium.com/@chandrarramalingam" />
<meta data-rh="true" name="author" content="Chandra Ramalingam" />
<meta data-rh="true" name="robots" content="index,follow,max-image-preview:large" />
<meta data-rh="true" name="referrer" content="unsafe-url" />
<meta data-rh="true" name="twitter:label1" value="Reading time" />
<meta data-rh="true" name="twitter:data1" value="18 min read" />
<meta data-rh="true" name="parsely-post-id" content="af688aa1b1b8" />
<link data-rh="true" rel="search" type="application/opensearchdescription+xml" title="Medium" href="/osd.xml" />
<link data-rh="true" rel="apple-touch-icon" sizes="152x152" href="https://miro.medium.com/fit/c/152/152/1*sHhtYhaCe2Uc3IU0IgKwIQ.png" />
<link data-rh="true" rel="apple-touch-icon" sizes="120x120" href="https://miro.medium.com/fit/c/120/120/1*sHhtYhaCe2Uc3IU0IgKwIQ.png" />
<link data-rh="true" rel="apple-touch-icon" sizes="76x76" href="https://miro.medium.com/fit/c/76/76/1*sHhtYhaCe2Uc3IU0IgKwIQ.png" />
<link data-rh="true" rel="apple-touch-icon" sizes="60x60" href="https://miro.medium.com/fit/c/60/60/1*sHhtYhaCe2Uc3IU0IgKwIQ.png" />
<link data-rh="true" rel="mask-icon" href="https://cdn-static-1.medium.com/_/fp/icons/Medium-Avatar-500x500.svg" color="#171717" />
<link data-rh="true" id="glyph_preload_link" rel="preload" as="style" type="text/css" href="https://glyph.medium.com/css/unbound.css" />
<link data-rh="true" id="glyph_link" rel="stylesheet" type="text/css" href="https://glyph.medium.com/css/unbound.css" />
<link data-rh="true" rel="author" href="https://medium.com/@chandrarramalingam" />
<link data-rh="true" rel="canonical" href="https://medium.com/walmartglobaltech/building-domain-driven-microservices-af688aa1b1b8" />
<link data-rh="true" rel="alternate" href="android-app://com.medium.reader/https/medium.com/p/af688aa1b1b8" />
<link data-rh="true" rel="icon" href="https://miro.medium.com/1*m-R_BkNf1Qjr1YbyOIJY2w.png" />
<script data-rh="true">
<![CDATA[
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-24232453-2', 'auto');
ga('send', 'pageview');
]]>
</script>
<link rel="preload" href="https://cdn.optimizely.com/js/16180790160.js" as="script" />
<style data-fela-type="KEYFRAME" type="text/css">
/*<![CDATA[*/
@-webkit-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@-moz-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="STATIC">
/*<![CDATA[*/
html{box-sizing:border-box}*, *:before, *:after{box-sizing:inherit}body{margin:0;padding:0;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:rgba(0,0,0,0.8);position:relative;min-height:100vh}h1, h2, h3, h4, h5, h6, dl, dd, ol, ul, menu, figure, blockquote, p, pre, form{margin:0}menu, ol, ul{padding:0;list-style:none;list-style-image:none}main{display:block}a{color:inherit;text-decoration:none}a, button, input{-webkit-tap-highlight-color:transparent}img, svg{vertical-align:middle}button{background:transparent;overflow:visible}button, input, optgroup, select, textarea{margin:0}:root{--reach-tabs:1;--reach-menu-button:1}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE">
/*<![CDATA[*/
.a{font-family:medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}.b{font-weight:400}.c{background-color:rgba(255, 255, 255, 1)}.l{height:100vh}.m{width:100vw}.n{display:flex}.o{align-items:center}.p{justify-content:center}.q{height:25px}.r{fill:rgba(41, 41, 41, 1)}.s{display:block}.t{position:absolute}.u{top:0}.v{left:0}.w{right:0}.x{z-index:500}.y{box-shadow:0 4px 12px 0 rgba(0, 0, 0, 0.05)}.ah{max-width:1192px}.ai{min-width:0}.aj{width:100%}.ak{height:65px}.an{flex:1 0 auto}.ao{fill:rgba(25, 25, 25, 1)}.ap{flex:0 0 auto}.aq{visibility:hidden}.ar{margin-left:16px}.as{color:rgba(26, 137, 23, 1)}.at{fill:rgba(26, 137, 23, 1)}.au{font-size:inherit}.av{border:inherit}.aw{font-family:inherit}.ax{letter-spacing:inherit}.ay{font-weight:inherit}.az{padding:0}.ba{margin:0}.be:disabled{cursor:default}.bf:disabled{color:rgba(163, 208, 162, 0.5)}.bg:disabled{fill:rgba(163, 208, 162, 0.5)}.bh{border-top:1px solid rgba(230, 230, 230, 1)}.bj{height:54px}.bk{overflow:hidden}.bl{margin-right:40px}.bm{height:36px}.bn{width:196px}.bo{overflow:auto}.bp{flex:0 1 auto}.bq{list-style-type:none}.br{line-height:40px}.bs{white-space:nowrap}.bt{overflow-x:auto}.bu{align-items:flex-start}.bv{margin-top:20px}.bw{padding-top:20px}.bx{height:80px}.by{height:20px}.bz{margin-right:15px}.ca{margin-left:15px}.cb:first-child{margin-left:0}.cc{min-width:1px}.cd{background-color:rgba(168, 168, 168, 1)}.ce{font-family:sohne, "Helvetica Neue", Helvetica, Arial, sans-serif}.cf{font-size:13px}.cg{line-height:20px}.ch{color:rgba(117, 117, 117, 1)}.ci{text-transform:uppercase}.cj{letter-spacing:1px}.ck{color:inherit}.cl{fill:inherit}.co:disabled{color:rgba(117, 117, 117, 1)}.cp:disabled{fill:rgba(117, 117, 117, 1)}.cq{margin-bottom:0px}.cr{margin-top:0px}.cs{height:119px}.cv{padding-left:24px}.cw{padding-right:24px}.cx{margin-left:auto}.cy{margin-right:auto}.cz{max-width:728px}.da{box-sizing:border-box}.db{top:calc(100vh + 100px)}.dc{bottom:calc(100vh + 100px)}.dd{width:10px}.de{pointer-events:none}.df{word-break:break-word}.dg{word-wrap:break-word}.dh:after{display:block}.di:after{content:""}.dj:after{clear:both}.dk{max-width:680px}.dl{line-height:1.23}.dm{letter-spacing:0}.dn{font-style:normal}.do{font-family:fell, Georgia, Cambria, "Times New Roman", Times, serif}.ej{margin-bottom:-0.27em}.ek{color:rgba(41, 41, 41, 1)}.el{margin-top:32px}.em{justify-content:space-between}.eq{border-radius:50%}.er{height:48px}.es{width:48px}.et{margin-left:12px}.eu{font-size:14px}.ev{margin-bottom:2px}.ex{max-height:20px}.ey{text-overflow:ellipsis}.ez{display:-webkit-box}.fa{-webkit-line-clamp:1}.fb{-webkit-box-orient:vertical}.fe{margin-left:8px}.ff{color:rgba(255, 255, 255, 1)}.fg{padding:0px 8px 1px}.fh{fill:rgba(255, 255, 255, 1)}.fi{background:rgba(26, 137, 23, 1)}.fj{border-color:rgba(26, 137, 23, 1)}.fm:disabled{cursor:inherit}.fn:disabled{opacity:0.3}.fo:disabled:hover{background:rgba(26, 137, 23, 1)}.fp:disabled:hover{border-color:rgba(26, 137, 23, 1)}.fq{border-radius:4px}.fr{border-width:1px}.fs{border-style:solid}.ft{display:inline-block}.fu{text-decoration:none}.fv{align-items:flex-end}.gd{padding-right:6px}.ge{fill:rgba(117, 117, 117, 1)}.gf{margin-right:8px}.gg{margin-right:-6px}.gh{max-width:1920px}.gn{clear:both}.gp{cursor:zoom-in}.gq{position:relative}.gr{z-index:auto}.gt{opacity:0}.gu{transition:opacity 100ms 400ms}.gv{height:100%}.gw{will-change:transform}.gx{transform:translateZ(0)}.gy{margin:auto}.gz{background-color:rgba(242, 242, 242, 1)}.ha{padding-bottom:52.916666666666664%}.hb{height:0}.hc{filter:blur(20px)}.hd{transform:scale(1.1)}.he{visibility:visible}.hf{margin-top:10px}.hg{text-align:center}.hj{text-decoration:underline}.hk{line-height:1.12}.hl{letter-spacing:-0.022em}.hm{font-weight:500}.ih{margin-bottom:-0.28em}.ii{line-height:1.58}.ij{letter-spacing:-0.004em}.ik{font-family:charter, Georgia, Cambria, "Times New Roman", Times, serif}.jd{margin-bottom:-0.46em}.je{font-weight:700}.jf{font-style:italic}.jl{list-style-type:decimal}.jm{
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="all and (min-width: 1080px)">
/*<![CDATA[*/
.d{display:none}.ag{margin:0 64px}.ef{font-size:48px}.eg{margin-top:0.55em}.eh{line-height:60px}.ei{letter-spacing:-0.011em}.gc{margin-left:30px}.gm{margin-top:56px}.id{font-size:30px}.ie{margin-top:1.95em}.if{line-height:36px}.ig{letter-spacing:0}.iz{font-size:21px}.ja{margin-top:0.86em}.jb{line-height:32px}.jc{letter-spacing:-0.003em}.jk{margin-top:2em}.js{margin-top:1.05em}.lp{margin-right:5px}.mf{margin-top:5px}.mr{padding-left:6px}.ng{display:inline-block}.nl{margin-left:7px}.nm{margin-top:8px}.nr{width:25px}.nz{padding-left:7px}.oa{top:3px}.px{font-size:22px}.py{line-height:28px}.ql{width:calc(100% + 32px)}.qm{margin-left:-16px}.qn{margin-right:-16px}.re{padding-left:16px}.rf{padding-right:16px}.rg{flex-basis:25%}.rh{max-width:25%}.rx{font-size:16px}.ry{line-height:20px}.sk{min-width:70px}.sl{min-height:70px}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="all and (max-width: 1079.98px)">
/*<![CDATA[*/
.e{display:none}.gb{margin-left:30px}.hh{margin-left:auto}.hi{text-align:center}.lo{margin-right:5px}.me{margin-top:5px}.mq{padding-left:6px}.nf{display:inline-block}.nj{margin-left:7px}.nk{margin-top:8px}.nq{width:25px}.nx{padding-left:7px}.ny{top:3px}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="all and (max-width: 903.98px)">
/*<![CDATA[*/
.f{display:none}.ga{margin-left:30px}.ln{margin-right:5px}.md{margin-top:5px}.mo{padding-left:6px}.mp{top:3px}.nd{display:inline-block}.nh{margin-left:7px}.ni{margin-top:8px}.np{width:15px}.nw{padding-left:3px}.rn{margin-right:16px}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="all and (max-width: 727.98px)">
/*<![CDATA[*/
.g{display:none}.al{height:56px}.am{display:flex}.bi{display:block}.ct{margin-bottom:0px}.cu{height:110px}.eo{margin-top:32px}.ep{flex-direction:column-reverse}.fy{margin-bottom:30px}.fz{margin-left:0px}.lm{margin-left:8px}.mb{margin-top:2px}.mc{margin-right:8px}.mm{padding-left:6px}.mn{top:3px}.nc{display:inline-block}.no{width:15px}.nv{padding-left:3px}.oe{padding-top:0}.oh{margin-bottom:24px}.oi{align-items:center}.oj{width:102px}.ok{position:relative}.on{padding-left:0}.oy{margin-top:24px}.pn{padding-bottom:12px}.po{margin-top:16px}.rm{margin-right:16px}.rz{margin-left:16px}.sa{margin-right:0px}.so{padding:32px 0}.td{width:140px}.te{margin-bottom:16px}.tf{margin-top:30px}.tg{width:100%}.th{flex-direction:row}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="all and (max-width: 551.98px)">
/*<![CDATA[*/
.h{display:none}.ab{margin:0 24px}.dp{font-size:34px}.dq{margin-top:0.56em}.dr{line-height:42px}.ds{letter-spacing:-0.016em}.en{margin-top:32px}.ew{margin-bottom:0px}.fw{margin-bottom:30px}.fx{margin-left:0px}.gi{margin-top:40px}.hn{font-size:22px}.ho{margin-top:1.2em}.hp{line-height:28px}.hq{letter-spacing:0}.il{font-size:18px}.im{margin-top:0.67em}.in{letter-spacing:-0.003em}.jg{margin-top:1.56em}.jo{margin-top:1.34em}.ll{margin-left:8px}.lz{margin-top:2px}.ma{margin-right:8px}.mk{padding-left:6px}.ml{top:3px}.nb{display:inline-block}.nn{width:15px}.nu{padding-left:3px}.pp{font-size:20px}.pq{line-height:24px}.pz{width:calc(100% + 24px)}.qa{margin-left:-12px}.qb{margin-right:-12px}.qo{padding-left:12px}.qp{padding-right:12px}.qq{flex-basis:100%}.qr{max-width:100%}.rl{margin-right:16px}.rp{font-size:16px}.rq{line-height:20px}.sc{min-width:48px}.sd{min-height:48px}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="all and (min-width: 904px) and (max-width: 1079.98px)">
/*<![CDATA[*/
.i{display:none}.af{margin:0 64px}.eb{font-size:48px}.ec{margin-top:0.55em}.ed{line-height:60px}.ee{letter-spacing:-0.011em}.gl{margin-top:56px}.hz{font-size:30px}.ia{margin-top:1.95em}.ib{line-height:36px}.ic{letter-spacing:0}.iv{font-size:21px}.iw{margin-top:0.86em}.ix{line-height:32px}.iy{letter-spacing:-0.003em}.jj{margin-top:2em}.jr{margin-top:1.05em}.pv{font-size:22px}.pw{line-height:28px}.qi{width:calc(100% + 32px)}.qj{margin-left:-16px}.qk{margin-right:-16px}.ra{padding-left:16px}.rb{padding-right:16px}.rc{flex-basis:25%}.rd{max-width:25%}.rv{font-size:16px}.rw{line-height:20px}.si{min-width:70px}.sj{min-height:70px}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="all and (min-width: 728px) and (max-width: 903.98px)">
/*<![CDATA[*/
.j{display:none}.ae{margin:0 48px}.dx{font-size:48px}.dy{margin-top:0.55em}.dz{line-height:60px}.ea{letter-spacing:-0.011em}.gk{margin-top:56px}.hv{font-size:30px}.hw{margin-top:1.95em}.hx{line-height:36px}.hy{letter-spacing:0}.ir{font-size:21px}.is{margin-top:0.86em}.it{line-height:32px}.iu{letter-spacing:-0.003em}.ji{margin-top:2em}.jq{margin-top:1.05em}.pt{font-size:22px}.pu{line-height:28px}.qf{width:calc(100% + 28px)}.qg{margin-left:-14px}.qh{margin-right:-14px}.qw{padding-left:14px}.qx{padding-right:14px}.qy{flex-basis:50%}.qz{max-width:50%}.rt{font-size:16px}.ru{line-height:20px}.sg{min-width:48px}.sh{min-height:48px}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="all and (min-width: 552px) and (max-width: 727.98px)">
/*<![CDATA[*/
.k{display:none}.ac{margin:0 24px}.dt{font-size:34px}.du{margin-top:0.56em}.dv{line-height:42px}.dw{letter-spacing:-0.016em}.gj{margin-top:40px}.hr{font-size:22px}.hs{margin-top:1.2em}.ht{line-height:28px}.hu{letter-spacing:0}.io{font-size:18px}.ip{margin-top:0.67em}.iq{letter-spacing:-0.003em}.jh{margin-top:1.56em}.jp{margin-top:1.34em}.pr{font-size:20px}.ps{line-height:24px}.qc{width:calc(100% + 24px)}.qd{margin-left:-12px}.qe{margin-right:-12px}.qs{padding-left:12px}.qt{padding-right:12px}.qu{flex-basis:100%}.qv{max-width:100%}.rr{font-size:16px}.rs{line-height:20px}.se{min-width:48px}.sf{min-height:48px}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="print">
/*<![CDATA[*/
.z{display:none}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="(orientation: landscape) and (max-width: 903.98px)">
/*<![CDATA[*/
.fc{max-height:none}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="(prefers-reduced-motion: no-preference)">
/*<![CDATA[*/
.go{transition:transform 300ms cubic-bezier(0.2, 0, 0.2, 1)}.kt{transition:opacity 200ms}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="all and (max-width: 1230px)">
/*<![CDATA[*/
.ku{display:none}
/*]]>*/
</style>
<style type="text/css" data-fela-rehydration="528" data-fela-type="RULE" media="all and (max-width: 1198px)">
/*<![CDATA[*/
.kw{display:none}
/*]]>*/
</style>
<script type="application/ld+json" data-rh="true">
<![CDATA[
{"@context":"http:\u002F\u002Fschema.org","@type":"NewsArticle","image":["https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F1200\u002F1*8xaltkmBH_FInTZe8nH1bQ.jpeg"],"url":"https:\u002F\u002Fmedium.com\u002Fwalmartglobaltech\u002Fbuilding-domain-driven-microservices-af688aa1b1b8","dateCreated":"2020-07-01T04:06:45.070Z","datePublished":"2020-07-01T04:06:45.070Z","dateModified":"2020-08-19T18:48:58.235Z","headline":"Building Domain Driven Microservices - Walmart Global Tech Blog - Medium","name":"Building Domain Driven Microservices - Walmart Global Tech Blog - Medium","description":"The term micro in Microservices, though indicative of the size of a service, is not the only criteria that make an application a Microservice. When teams move to a microservices-based architecture…","identifier":"af688aa1b1b8","keywords":["Lite:true","Tag:Microservices","Tag:Distributed Systems","Tag:Domain Driven Design","Tag:Bounded Context","Publication:walmartglobaltech","Elevated:false","LockedPostSource:LOCKED_POST_SOURCE_UGC_UNENROLLED","LayerCake:3"],"author":{"@type":"Person","name":"Chandra Ramalingam","url":"https:\u002F\u002Fmedium.com\u002F@chandrarramalingam"},"creator":["Chandra Ramalingam"],"publisher":{"@type":"Organization","name":"Walmart Global Tech Blog","url":"https:\u002F\u002Fmedium.com\u002Fwalmartglobaltech","logo":{"@type":"ImageObject","width":325,"height":60,"url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F325\u002F1*8BhtOzg5TgZmRkRbzP05Jw.jpeg"}},"mainEntityOfPage":"https:\u002F\u002Fmedium.com\u002Fwalmartglobaltech\u002Fbuilding-domain-driven-microservices-af688aa1b1b8","isAccessibleForFree":"False","hasPart":{"@type":"WebPageElement","isAccessibleForFree":"False","cssSelector":".meteredContent"}}
]]>
</script>
<script type="text/javascript" data-rh="true">
//<![CDATA[
(function(b,r,a,n,c,h,_,s,d,k){if(!b[n]||!b[n]._q){for(;s<_.length;)c(h,_[s++]);d=r.createElement(a);d.async=1;d.src="https://cdn.branch.io/branch-latest.min.js";k=r.getElementsByTagName(a)[0];k.parentNode.insertBefore(d,k);b[n]=h}})(window,document,"script","branch",function(b,r){b[r]=function(){b._q.push([r,arguments])}},{_q:[],_v:1},"addListener applyCode autoAppIndex banner closeBanner closeJourney creditHistory credits data deepview deepviewCta first getCode init link logout redeem referrals removeListener sendSMS setBranchViewData setIdentity track validateCode trackCommerceEvent logEvent".split(" "), 0);
branch.init('key_live_ofxXr2qTrrU9NqURK8ZwEhknBxiI6KBm', {metadata: {}, 'no_journeys': true, 'disable_exit_animation': true, 'disable_entry_animation': true, 'tracking_disabled': null}, function(err, data) {});
//]]>
</script>
<style id="googleidentityservice_button_styles">
<![CDATA[
.qJTHM{-moz-user-select:none;color:#202124;direction:ltr;font-family:'Roboto-Regular',arial,sans-serif;font-weight:400;margin:0;overflow:hidden}.ynRLnc{left:-9999px;position:absolute;top:-9999px}.L6cTce{display:none}.bltWBb{word-break:break-all}.hSRGPd{color:#1a73e8;cursor:pointer;font-weight:500;text-decoration:none}.Bz112c-W3lGp{height:16px;width:16px}.Bz112c-E3DyYd{height:20px;width:20px}.Bz112c-r9oPif{height:24px;width:24px}.Bz112c-uaxL4e{-moz-border-radius:10px;border-radius:10px}.LgbsSe-Bz112c{display:block}.S9gUrf-YoZ4jf,.S9gUrf-YoZ4jf *{border:none;margin:0;padding:0}.fFW7wc-ibnC6b>.aZ2wEe>div{border-color:#4285f4}.P1ekSe-ZMv3u>div:nth-child(1){background-color:#1a73e8!important}.P1ekSe-ZMv3u>div:nth-child(2),.P1ekSe-ZMv3u>div:nth-child(3){background-image:linear-gradient(to right,rgba(255,255,255,0.7),rgba(255,255,255,0.7)),linear-gradient(to right,#1a73e8,#1a73e8)!important}.haAclf{display:inline-block}.nsm7Bb-HzV7m-LgbsSe{border-radius:4px;box-sizing:border-box;transition:background-color .218s,border-color .218s;-moz-user-select:none;background-color:#fff;background-image:none;border:1px solid #dadce0;color:#3c4043;cursor:pointer;font-family:'Google Sans',arial,sans-serif;font-size:14px;height:40px;letter-spacing:.25px;outline:none;overflow:hidden;padding:0 12px;position:relative;text-align:center;vertical-align:middle;white-space:nowrap;width:auto}@media screen and (-ms-high-contrast:active){.nsm7Bb-HzV7m-LgbsSe{border:2px solid windowText;color:windowText}}.nsm7Bb-HzV7m-LgbsSe.pSzOP-SxQuSe{font-size:14px;height:32px;letter-spacing:.25px;padding:0 10px}.nsm7Bb-HzV7m-LgbsSe.purZT-SxQuSe{font-size:11px;height:20px;letter-spacing:.3px;padding:0 8px}.nsm7Bb-HzV7m-LgbsSe.Bz112c-LgbsSe{padding:0;width:40px}.nsm7Bb-HzV7m-LgbsSe.Bz112c-LgbsSe.pSzOP-SxQuSe{width:32px}.nsm7Bb-HzV7m-LgbsSe.Bz112c-LgbsSe.purZT-SxQuSe{width:20px}.nsm7Bb-HzV7m-LgbsSe.JGcpL-RbRzK{border-radius:20px}.nsm7Bb-HzV7m-LgbsSe.JGcpL-RbRzK.pSzOP-SxQuSe{border-radius:16px}.nsm7Bb-HzV7m-LgbsSe.JGcpL-RbRzK.purZT-SxQuSe{border-radius:10px}.nsm7Bb-HzV7m-LgbsSe.MFS4be-Ia7Qfc{border:none;color:#fff}.nsm7Bb-HzV7m-LgbsSe.MFS4be-v3pZbf-Ia7Qfc{background-color:#1a73e8}.nsm7Bb-HzV7m-LgbsSe.MFS4be-JaPV2b-Ia7Qfc{background-color:#202124;color:#e8eaed}.nsm7Bb-HzV7m-LgbsSe .nsm7Bb-HzV7m-LgbsSe-Bz112c{height:18px;margin-right:8px;min-width:18px;width:18px}.nsm7Bb-HzV7m-LgbsSe.pSzOP-SxQuSe .nsm7Bb-HzV7m-LgbsSe-Bz112c{height:14px;min-width:14px;width:14px}.nsm7Bb-HzV7m-LgbsSe.purZT-SxQuSe .nsm7Bb-HzV7m-LgbsSe-Bz112c{height:10px;min-width:10px;width:10px}.nsm7Bb-HzV7m-LgbsSe.jVeSEe .nsm7Bb-HzV7m-LgbsSe-Bz112c{margin-left:8px;margin-right:-4px}.nsm7Bb-HzV7m-LgbsSe.Bz112c-LgbsSe .nsm7Bb-HzV7m-LgbsSe-Bz112c{margin:0;padding:10px}.nsm7Bb-HzV7m-LgbsSe.Bz112c-LgbsSe.pSzOP-SxQuSe .nsm7Bb-HzV7m-LgbsSe-Bz112c{padding:8px}.nsm7Bb-HzV7m-LgbsSe.Bz112c-LgbsSe.purZT-SxQuSe .nsm7Bb-HzV7m-LgbsSe-Bz112c{padding:4px}.nsm7Bb-HzV7m-LgbsSe .nsm7Bb-HzV7m-LgbsSe-Bz112c-haAclf{border-top-left-radius:3px;border-bottom-left-radius:3px;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;justify-content:center;align-items:center;background-color:#fff;height:36px;margin-left:-10px;margin-right:12px;min-width:36px;width:36px}.nsm7Bb-HzV7m-LgbsSe .nsm7Bb-HzV7m-LgbsSe-Bz112c-haAclf .nsm7Bb-HzV7m-LgbsSe-Bz112c,.nsm7Bb-HzV7m-LgbsSe.Bz112c-LgbsSe .nsm7Bb-HzV7m-LgbsSe-Bz112c-haAclf .nsm7Bb-HzV7m-LgbsSe-Bz112c{margin:0;padding:0}.nsm7Bb-HzV7m-LgbsSe.pSzOP-SxQuSe .nsm7Bb-HzV7m-LgbsSe-Bz112c-haAclf{height:28px;margin-left:-8px;margin-right:10px;min-width:28px;width:28px}.nsm7Bb-HzV7m-LgbsSe.purZT-SxQuSe .nsm7Bb-HzV7m-LgbsSe-Bz112c-haAclf{height:16px;margin-left:-6px;margin-right:8px;min-width:16px;width:16px}.nsm7Bb-HzV7m-LgbsSe.Bz112c-LgbsSe .nsm7Bb-HzV7m-LgbsSe-Bz112c-haAclf{border-radius:3px;margin-left:2px;margin-right:0;padding:0}.nsm7Bb-HzV7m-LgbsSe.JGcpL-RbRzK .nsm7Bb-HzV7m-LgbsSe-Bz112c-haAclf{border-radius:18px}.nsm7Bb-HzV7m-LgbsSe.pSzOP-SxQuSe.JGcpL-RbRzK .nsm7Bb-HzV7m-LgbsSe-Bz112c-haAclf{border-radius:14px}.nsm7Bb-HzV7m-LgbsSe.purZT-SxQuSe.JGcpL-R
/*# sourceURL=/_/gsi/_/ss/k=gsi.gsi.d2Sws5Qy19A.L.F4.O/am=UgE/d=1/ct=zgms/rs=AF0KOtXRk1BfVJqouGYksMSadiVP5-w0qw/m=gis_client_button_style */
]]>
</style>
<link id="googleidentityservice" type="text/css" media="all" rel="stylesheet" href="https://accounts.google.com/gsi/style" />
</head>
<body>
<div id="root">
<div class="a b c">
<div class="d e f g h i j k"></div>
<script>
<![CDATA[
document.domain = document.domain;
]]>
</script>
<div>
<script>
<![CDATA[
if (window.self !== window.top) window.location = "about:blank"
]]>
</script>
</div>
<script>
<![CDATA[
window.PARSELY = window.PARSELY || {autotrack: false}
]]>
</script>
<div class="s">
<nav class="s t u v w c x y z">
<div>
<div class="s c">
<div class="n p">
<div class="ab ac ae af ag ah ai aj">
<div class="ak n o al am">
<div class="n o an x">
<a rel="noopener" href="/?source=post_page-----af688aa1b1b8--------------------------------"><svg viewbox="0 0 1043.63 592.71" class="q ao">
<g data-name="Layer 2">
<g data-name="Layer 1">
<path d="M588.67 296.36c0 163.67-131.78 296.35-294.33 296.35S0 460 0 296.36 131.78 0 294.34 0s294.33 132.69 294.33 296.36M911.56 296.36c0 154.06-65.89 279-147.17 279s-147.17-124.94-147.17-279 65.88-279 147.16-279 147.17 124.9 147.17 279M1043.63 296.36c0 138-23.17 249.94-51.76 249.94s-51.75-111.91-51.75-249.94 23.17-249.94 51.75-249.94 51.76 111.9 51.76 249.94"></path>
</g>
</g></svg></a>
</div>
<div class="s ap x">
<div class="n o">
<div class="n o g">
<div class="he" id="lo-post-page-navbar-sign-in-link">
<div class="ar s">
<span><a href="https://medium.com/m/signin?operation=login&amp;redirect=https%3A%2F%2Fmedium.com%2Fwalmartglobaltech%2Fbuilding-domain-driven-microservices-af688aa1b1b8&amp;source=post_page-----af688aa1b1b8---------------------nav_reg-----------" class="as at au av aw ax ay az ba bb bc bd be bf bg" rel="noopener">Sign in</a></span>
</div>
</div>
</div>
<div class="ox am oi">
<div class="he" id="lo-ShowPostUnderCollection-navbar-open-in-app-button">
<div class="ar ox bi">
<span class="ce b eu cg ch"><a href="https://rsci.app.link/?%24canonical_url=https%3A%2F%2Fmedium.com%2Fp%2Faf688aa1b1b8&amp;~feature=LoOpenInAppButton&amp;~channel=ShowPostUnderCollection&amp;~stage=mobileNavBar&amp;source=post_page-----af688aa1b1b8--------------------------------" class="as at au av aw ax ay az ba bb bc bd be tj tk" rel="noopener nofollow">Open in app</a></span>
</div>
</div>
</div>
<div class="he" id="lo-post-page-navbar-sign-in-button">
<div class="ar s">
<span><button class="ce b eu cg as lg tm at fj bc bd fl bb fm fn tn to fp fq fr fs da ft fu">Get started</button></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="bh s c bi">
<div class="n p">
<div class="ab ac ae af ag ah ai aj">
<div class="bj bk n o">
<div class="bl s ap">
<a href="/walmartglobaltech?source=post_page-----af688aa1b1b8--------------------------------" rel="noopener">
<div class="bm bn s">
<img alt="Walmart Global Tech Blog" class="" src="https://miro.medium.com/max/392/1*8BhtOzg5TgZmRkRbzP05Jw.jpeg" width="196" height="36" />
</div></a>
</div>
<div class="bo s bp">
<ul class="bq ba br bs bt n bu g bv bw bx">
<li class="n o by bz ca cb">
<span class="ce b cf cg ch ci cj"><a href="https://medium.com/walmartglobaltech/tagged/engineering?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">Engineering</a></span>
</li>
<li class="n o by bz ca cb">
<span class="ce b cf cg ch ci cj"><a href="https://medium.com/walmartglobaltech/tagged/data-science?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">Data Science</a></span>
</li>
<li class="n o by bz ca cb">
<span class="ce b cf cg ch ci cj"><a href="https://medium.com/walmartglobaltech/tagged/infosec?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">InfoSec</a></span>
</li>
<li class="n o by bz ca cb">
<span class="ce b cf cg ch ci cj"><a href="https://medium.com/walmartglobaltech/tagged/ux-design?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">UX Design</a></span>
</li>
<li class="n o by bz ca cb">
<span class="ce b cf cg ch ci cj"><a href="https://medium.com/walmartglobaltech/tagged/leadership?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">Leadership</a></span>
</li>
<li class="n o by bz ca cb">
<span class="ce b cf cg ch ci cj"><a href="https://www.linkedin.com/company/walmartglobaltech/?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener nofollow">About</a></span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</nav>
<div class="cq cr cs s ct cu"></div>
<div class="s z">
<div class="ul um aj gv ko un uo lt gt up de" aria-hidden="true"></div>
<div class="uq ko ur us ud ul gv da bo ut uu tx uv uw ux tg uy uz va vb ox" aria-hidden="true">
<div class="ve vf n o lh em">
<h2 class="ce hm sy ow dm ek">
Responses (5)
</h2>
<div class="n lh">
<div>
<div class="ft" role="tooltip" aria-hidden="false" aria-describedby="1" aria-labelledby="1">
<a href="https://policy.medium.com/medium-rules-30e5502c4eb4?source=responses-----af688aa1b1b8--------------------------------" class="vg cn" target="_blank" rel="noopener"><svg width="25" height="25" viewbox="0 0 25 25">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.99 5.04c.26-.21.64-.22.91-.01.97.72 1.77 1.21 2.6 1.54.83.32 1.72.48 2.89.5.41.01.74.35.74.76-.02 3.62-.43 6.26-1.45 8.21-1.03 1.98-2.66 3.21-4.97 4.08a.75.75 0 0 1-.53 0c-2.25-.87-3.86-2.1-4.9-4.07-1.02-1.95-1.46-4.59-1.48-8.22 0-.41.33-.75.75-.76 1.19-.02 2.1-.18 2.92-.5.82-.32 1.6-.81 2.52-1.53zm.46.9c-.9.69-1.71 1.21-2.62 1.56a8.9 8.9 0 0 1-3.02.57c.03 3.45.46 5.82 1.36 7.51.88 1.69 2.25 2.77 4.28 3.57 2.1-.8 3.47-1.89 4.34-3.57.89-1.7 1.3-4.07 1.34-7.51a8.8 8.8 0 0 1-3-.57 11.8 11.8 0 0 1-2.68-1.56zm0 9.15a2.67 2.67 0 1 0 0-5.34 2.67 2.67 0 0 0 0 5.34zm0 1a3.67 3.67 0 1 0 0-7.34 3.67 3.67 0 0 0 0 7.34zm-1.82-3.77l.53-.53.91.92 1.63-1.63.52.53-2.15 2.15-1.44-1.44z"></path></svg></a>
</div>
</div>
<div class="s gq vh">
<div class="ba s gq w">
<button class="ck cl au av aw ax ay az ba bb cm cn be co cp" data-testid="close-button" aria-label="close"><svg width="25" height="25" viewbox="0 0 25 25" class="ge">
<path d="M18.13 6.11l-5.61 5.61-5.6-5.61-.81.8 5.61 5.61-5.61 5.61.8.8 5.61-5.6 5.61 5.6.8-.8-5.6-5.6 5.6-5.62"></path></svg></button>
</div>
</div>
</div>
</div>
<div class="vi s">
<div class="vj vk">
<div class="n lh">
<div class="vl vm vn s gz"></div>
<div class="fe vo s">
<div class="mv vp vq s gz"></div>
<div class="vp ol s gz"></div>
</div>
</div>
<div class="vr s">
<div class="mv vs aj s gz"></div>
<div class="mv vs aj s gz"></div>
<div class="vs vt s gz"></div>
</div>
</div>
</div>
</div>
</div>
<article class="meteredContent">
<section class="cv cw cx cy aj cz da s">
<div>
<div class="he" id="lo-highlight-meter-1-highlight-box">
<div class="tp fq tq gq tr">
<div class="ts tt n em tu">
<p class="ce b kz ow ek">
<span class="he" id="lo-highlight-meter-1-copy">You have <b>2</b> free member-only stories left this month.</span>
</p>
<div class="tv bs">
<span class="he" id="lo-highlight-meter-1-link"><span><a href="https://medium.com/m/signin?operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fwalmartglobaltech%2Fbuilding-domain-driven-microservices-af688aa1b1b8&amp;source=-----af688aa1b1b8---------------------smart_meter-----------" class="ck cl au av aw ax ay az ba bb be co cp hj" rel="noopener">Sign up for Medium and get an extra one</a></span></span>
</div>
</div>
</div>
</div>
</div>
</section>
<div>
<div class="t v ua dc dd de"></div>
<div class="cx cy cz gq">
<div class="s h g f e">
<aside class="ud t u" style="width: 564px;">
<div class="ug uh t ui bs aj">
<p class="ce b cf cg ch">
<span class="ft uh bs bk ey">Top highlight</span>
</p>
</div>
</aside>
</div>
</div>
<section class="df dg dh di dj">
<div class="n p">
<div class="ab ac ae af ag dk ai aj">
<div class="">
<h1 id="3418" class="dl dm dn do b dp dq dr ds dt du dv dw dx dy dz ea eb ec ed ee ef eg eh ei ej ek">
Building Domain Driven Microservices
</h1>
<div class="el">
<div class="n em en eo ep">
<div class="o n">
<div>
<a rel="noopener" href="/@chandrarramalingam?source=post_page-----af688aa1b1b8--------------------------------"><img alt="Chandra Ramalingam" class="s eq er es" src="https://miro.medium.com/fit/c/96/96/1*nMWlywHdNTt8EoNNNPUzdw.jpeg" width="48" height="48" /></a>
</div>
<div class="et aj s">
<div class="n">
<div style="flex:1">
<div class="ev n o ew">
<span class="ce b eu cg ek"><span class="ce b eu cg bk ex ey ez fa fb fc ek"><a class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener" href="/@chandrarramalingam?source=post_page-----af688aa1b1b8--------------------------------">Chandra Ramalingam</a></span></span>
<div class="fe s ap h">
<span><button class="ce b cf cg ff fg fh fi fj fk fl bb fm fn fo fp fq fr fs da ft fu">Follow</button></span>
</div>
</div>
</div>
</div>
<div>
<span class="ce b eu cg ch"><a class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener" href="/walmartglobaltech/building-domain-driven-microservices-af688aa1b1b8?source=post_page-----af688aa1b1b8--------------------------------">Jul 1, 2020</a> <!-- -->·<!-- --> <!-- -->18<!-- --> min read<span style="padding-left:4px"><svg class="star-15px_svg__svgIcon-use" width="15" height="15" viewbox="0 0 15 15" style="margin-top:-2px">
<path d="M7.44 2.32c.03-.1.09-.1.12 0l1.2 3.53a.29.29 0 0 0 .26.2h3.88c.11 0 .13.04.04.1L9.8 8.33a.27.27 0 0 0-.1.29l1.2 3.53c.03.1-.01.13-.1.07l-3.14-2.18a.3.3 0 0 0-.32 0L4.2 12.22c-.1.06-.14.03-.1-.07l1.2-3.53a.27.27 0 0 0-.1-.3L2.06 6.16c-.1-.06-.07-.12.03-.12h3.89a.29.29 0 0 0 .26-.19l1.2-3.52z"></path></svg></span></span>
</div>
</div>
</div>
<div class="n fv fw fx fy fz ga gb gc z">
<div class="n o">
<div class="gd s ap">
<button class="ck cl au av aw ax ay az ba bb cm cn be co cp" aria-label="Share on twitter"><svg width="29" height="29" class="ge">
<path d="M22.05 7.54a4.47 4.47 0 0 0-3.3-1.46 4.53 4.53 0 0 0-4.53 4.53c0 .35.04.7.08 1.05A12.9 12.9 0 0 1 5 6.89a5.1 5.1 0 0 0-.65 2.26c.03 1.6.83 2.99 2.02 3.79a4.3 4.3 0 0 1-2.02-.57v.08a4.55 4.55 0 0 0 3.63 4.44c-.4.08-.8.13-1.21.16l-.81-.08a4.54 4.54 0 0 0 4.2 3.15 9.56 9.56 0 0 1-5.66 1.94l-1.05-.08c2 1.27 4.38 2.02 6.94 2.02 8.3 0 12.86-6.9 12.84-12.85.02-.24 0-.43 0-.65a8.68 8.68 0 0 0 2.26-2.34c-.82.38-1.7.62-2.6.72a4.37 4.37 0 0 0 1.95-2.51c-.84.53-1.81.9-2.83 1.13z"></path></svg></button>
</div>
<div class="gd s ap">
<button class="ck cl au av aw ax ay az ba bb cm cn be co cp" aria-label="Share on linkedin"><svg width="29" height="29" viewbox="0 0 29 29" fill="none" class="ge">
<path d="M5 6.36C5 5.61 5.63 5 6.4 5h16.2c.77 0 1.4.61 1.4 1.36v16.28c0 .75-.63 1.36-1.4 1.36H6.4c-.77 0-1.4-.6-1.4-1.36V6.36z"></path>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.76 20.9v-8.57H7.89v8.58h2.87zm-1.44-9.75c1 0 1.63-.65 1.63-1.48-.02-.84-.62-1.48-1.6-1.48-.99 0-1.63.64-1.63 1.48 0 .83.62 1.48 1.59 1.48h.01zM12.35 20.9h2.87v-4.79c0-.25.02-.5.1-.7.2-.5.67-1.04 1.46-1.04 1.04 0 1.46.8 1.46 1.95v4.59h2.87v-4.92c0-2.64-1.42-3.87-3.3-3.87-1.55 0-2.23.86-2.61 1.45h.02v-1.24h-2.87c.04.8 0 8.58 0 8.58z" fill="#fff"></path></svg></button>
</div>
<div class="gd s ap">
<button class="ck cl au av aw ax ay az ba bb cm cn be co cp" aria-label="Share on facebook"><svg width="29" height="29" class="ge">
<path d="M23.2 5H5.8a.8.8 0 0 0-.8.8V23.2c0 .44.35.8.8.8h9.3v-7.13h-2.38V13.9h2.38v-2.38c0-2.45 1.55-3.66 3.74-3.66 1.05 0 1.95.08 2.2.11v2.57h-1.5c-1.2 0-1.48.57-1.48 1.4v1.96h2.97l-.6 2.97h-2.37l.05 7.12h5.1a.8.8 0 0 0 .79-.8V5.8a.8.8 0 0 0-.8-.79"></path></svg></button>
</div>
<div class="gf s">
<div class="ge">
<span><a href="https://medium.com/m/signin?actionUrl=%2F_%2Fbookmark%2Fp%2Faf688aa1b1b8&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fwalmartglobaltech%2Fbuilding-domain-driven-microservices-af688aa1b1b8&amp;source=post_actions_header--------------------------bookmark_preview-----------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener"><svg width="25" height="25" viewbox="0 0 25 25">
<path d="M19 6a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v14.66h.01c.01.1.05.2.12.28a.5.5 0 0 0 .7.03l5.67-4.12 5.66 4.13a.5.5 0 0 0 .71-.03.5.5 0 0 0 .12-.29H19V6zm-6.84 9.97L7 19.64V6a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v13.64l-5.16-3.67a.49.49 0 0 0-.68 0z" fill-rule="evenodd"></path></svg></a></span>
</div>
</div>
<div class="gg s an"></div>
</div>
</div>
</div>
</div>
</div>
<figure class="gi gj gk gl gm gn cx cy paragraph-image">
<div role="button" tabindex="0" class="go gp gq gr aj gs">
<div class="cx cy gh">
<div class="gy s gq gz">
<div class="ha hb s">
<div class="gt gu t u v gv aj bk gw gx"></div><img alt="Image for post" class="tx ty t u v gv aj c" width="1920" height="1016" src="https://miro.medium.com/max/1920/1*8xaltkmBH_FInTZe8nH1bQ.jpeg" srcset="https://miro.medium.com/max/276/1*8xaltkmBH_FInTZe8nH1bQ.jpeg 276w, https://miro.medium.com/max/552/1*8xaltkmBH_FInTZe8nH1bQ.jpeg 552w, https://miro.medium.com/max/640/1*8xaltkmBH_FInTZe8nH1bQ.jpeg 640w, https://miro.medium.com/max/700/1*8xaltkmBH_FInTZe8nH1bQ.jpeg 700w" sizes="700px" /><noscript><img alt="Image for post" class="t u v gv aj" src="https://miro.medium.com/max/3840/1*8xaltkmBH_FInTZe8nH1bQ.jpeg" width="1920" height="1016" srcset="https://miro.medium.com/max/552/1*8xaltkmBH_FInTZe8nH1bQ.jpeg 276w, https://miro.medium.com/max/1104/1*8xaltkmBH_FInTZe8nH1bQ.jpeg 552w, https://miro.medium.com/max/1280/1*8xaltkmBH_FInTZe8nH1bQ.jpeg 640w, https://miro.medium.com/max/1400/1*8xaltkmBH_FInTZe8nH1bQ.jpeg 700w" sizes="700px" /></noscript>
</div>
</div>
</div>
</div>
<figcaption class="hf hg cz cx cy hh hi ce b eu cg ch" data-selectable-paragraph="">
Image credits: <a href="https://pixabay.com/illustrations/system-web-network-connection-3699542/" class="ck hj" rel="noopener nofollow">Pixabay</a>
</figcaption>
</figure>
<h1 id="2fa4" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
<strong class="ay">Microservices — a definition</strong>
</h1>
<p id="9199" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
The term micro in Microservices, though indicative of the size of a service, is not the only criteria that make an application a Microservice. When teams move to a microservices-based architecture, they aim to increase their agility — deploy features autonomously and frequently. Its hard to pin down a single concise definition of this architectural style. I liked this short definition from <a class="ck hj" rel="noopener" href="/@adrianco">Adrian Cockcroft</a><strong class="ik je"><em class="jf">serviceoriented architecture composed of loosely coupled elements that have bounded contexts</em>.”</strong>
</p>
<p id="cd81" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Though this defines a high-level design heuristic, Microservices architecture has some unique characteristics that differentiate it from the service-oriented architecture of the yesteryear. A few of those characteristics, below. These and a few more are well-documented — <a href="https://martinfowler.com/articles/microservices.html" class="ck hj" rel="noopener nofollow">Martin Fowlers article</a> and <a href="https://www.walmart.com/ip/Building-Microservices-Designing-Fine-Grained-Systems-9781491950357/40970629" class="ck hj" rel="noopener nofollow">Sam Newmans Building Microservices,</a> to name a few.
</p>
<ol class="">
<li id="f4bb" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd jl jm jn ek" data-selectable-paragraph="">Services have well-defined boundaries centered around business context, and not around arbitrary technical abstractions
</li>
<li id="deab" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Hide implementation detail and expose functionality through intention-revealing interfaces
</li>
<li id="0365" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Services dont share their internal structures beyond their boundaries. For example, no sharing of databases.
</li>
<li id="8fee" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Services are resilient to failures.
</li>
<li id="978e" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">
<mark class="ue uf lt">Teams own their functions independently and have the ability to release changes autonomously</mark>
</li>
<li id="5967" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Teams embrace a culture of automation. For example, automated testing, continuous integration and continuous delivery
</li>
</ol>
<p id="5d42" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
In short, we can summarize this architecture style <em class="jf">as below:</em>
</p>
<blockquote class="jt ju jv">
<p id="a73c" class="ii ij jf ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
<strong class="ik je">Loosely coupled service-oriented architecture, where each service is enclosed within a well-defined bounded context, enabling rapid, frequent, and reliable delivery of applications.</strong>
</p>
</blockquote>
<h1 id="85df" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
<strong class="ay">Domain-driven design and Bounded contexts</strong>
</h1>
<p id="0dc0" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
The power of microservices comes from clearly defining their responsibility and demarcating the boundary between them. The purpose here is to build high cohesion within the boundary and low coupling outside of it. That is, things that tend to change together should belong together. As in many real-life problems, this is easier said than done — businesses evolve, and assumptions change. Hence the ability to refactor is another critical thing to consider when designing systems.
</p>
<p id="a55b" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Domain-driven design (DDD) is a key, and in our opinion, a necessary tool when designing microservices, be it breaking a monolith or implementing a greenfield project. Domain-driven design, made famous by Eric Evans by his <a href="https://www.walmart.com/ip/Domain-Driven-Design-Tackling-Complexity-in-the-Heart-of-Software-Hardcover-9780321125217/2222375" class="ck hj" rel="noopener nofollow">book</a> , is a set of ideas, principles, and patterns that help design software systems based on the underlying model of the business domain. The developers and domain experts work together to create business models in a Ubiquitous common <em class="jf">language.</em> They then bind these models to systems where they make sense, establish collaboration protocols between these systems and the teams that work on these services. More importantly, they design the conceptual contours or boundaries between the systems.
</p>
<p id="285f" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Microservice design draws inspiration from these concepts as all of these principles help build modular systems that can change and evolve independently of one another.
</p>
<p id="6a57" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Before we proceed further, lets quickly go through some of the basic terminologies of DDD. A full overview of Domain-Driven Design is out of scope for this blog. We highly recommend Eric Evans <a href="https://www.walmart.com/ip/Domain-Driven-Design-Tackling-Complexity-in-the-Heart-of-Software-Hardcover-9780321125217/2222375" class="ck hj" rel="noopener nofollow">book</a> to anyone trying to build microservices
</p>
<p id="14cf" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
<strong class="ik je">Domain:</strong> Represents what an organization does. In the below example, it would be Retail or eCommerce.
</p>
<p id="388f" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
<strong class="ik je">Subdomain:</strong> An organization or business unit within an organization. A domain is composed of multiple subdomains.
</p>
<p id="360e" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
<strong class="ik je">Ubiquitous language:</strong> This is the language used to express the models. In the example below, Item is a Model that belongs to the Ubiquitous language of each of these subdomains. Developers, Product Managers, domain experts, and business stakeholders agree on the same language and use it in their artifacts — Code, Product Documentation, and so on.
</p>
<figure class="gi gj gk gl gm gn cx cy paragraph-image">
<div class="cx cy jw">
<div class="gy s gq gz">
<div class="jx hb s">
<div class="gt gu t u v gv aj bk gw gx"></div><img alt="Image for post" class="tx ty t u v gv aj c" width="666" height="626" src="https://miro.medium.com/max/666/1*CQSDhnewuP6sVxJJNuA_VA.png" srcset="https://miro.medium.com/max/276/1*CQSDhnewuP6sVxJJNuA_VA.png 276w, https://miro.medium.com/max/552/1*CQSDhnewuP6sVxJJNuA_VA.png 552w, https://miro.medium.com/max/640/1*CQSDhnewuP6sVxJJNuA_VA.png 640w, https://miro.medium.com/max/666/1*CQSDhnewuP6sVxJJNuA_VA.png 666w" sizes="666px" /><noscript><img alt="Image for post" class="t u v gv aj" src="https://miro.medium.com/max/1332/1*CQSDhnewuP6sVxJJNuA_VA.png" width="666" height="626" srcset="https://miro.medium.com/max/552/1*CQSDhnewuP6sVxJJNuA_VA.png 276w, https://miro.medium.com/max/1104/1*CQSDhnewuP6sVxJJNuA_VA.png 552w, https://miro.medium.com/max/1280/1*CQSDhnewuP6sVxJJNuA_VA.png 640w, https://miro.medium.com/max/1332/1*CQSDhnewuP6sVxJJNuA_VA.png 666w" sizes="666px" /></noscript>
</div>
</div>
</div>
<figcaption class="hf hg cz cx cy hh hi ce b eu cg ch" data-selectable-paragraph="">
Fig 1. Sub-domains and Bounded Contexts in eCommerce domain
</figcaption>
</figure>
<p id="e6be" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
<strong class="ik je">Bounded Contexts:</strong> Domain-driven design defines Bounded contexts as <em class="jf">“The setting in which a word or a statement appears that determines its meaning.”</em> In short, this means the boundary within which a model makes sense. In the above example, “Item” takes on a different meaning in each of those contexts. In the Catalog context, an Item means a sell-able product, whereas, in Cart context, it means the item that the customer has added to her cart. In Fulfillment context, it means a Warehouse Item that will be shipped to the customer. Each of these models is different, and each has a different meaning and possibly contains different attributes. By separating and isolating these models within their respective boundaries, we can express the models freely and without ambiguity.
</p>
<p id="76e1" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
<strong class="ik je">Note</strong>: Its essential to understand the distinction between Subdomains and Bounded contexts. A subdomain belongs in the problem space, that is, how your business sees the problem, whereas Bounded contexts belong in the solution space, that is, how we will implement the solution to the problem. Theoretically, each subdomain may have multiple bounded contexts, though we strive for one bounded context per subdomain.
</p>
<h1 id="26ef" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
<strong class="ay">How are Microservices related to Bounded contexts</strong>
</h1>
<p id="91b1" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
Now, where do Microservices fit? Is it fair to say that each bounded context maps to a microservice? Yes and no. We will see why. There may be cases where the boundary or contour of your bounded context is quite large.
</p>
<figure class="gi gj gk gl gm gn cx cy paragraph-image">
<div class="cx cy jy">
<div class="gy s gq gz">
<div class="jz hb s">
<div class="gt gu t u v gv aj bk gw gx"></div><img alt="Image for post" class="tx ty t u v gv aj c" width="558" height="402" src="https://miro.medium.com/max/558/1*CRq9QlIpGlTx4-fQ2Hg73A.png" srcset="https://miro.medium.com/max/276/1*CRq9QlIpGlTx4-fQ2Hg73A.png 276w, https://miro.medium.com/max/552/1*CRq9QlIpGlTx4-fQ2Hg73A.png 552w, https://miro.medium.com/max/558/1*CRq9QlIpGlTx4-fQ2Hg73A.png 558w" sizes="558px" /><noscript><img alt="Image for post" class="t u v gv aj" src="https://miro.medium.com/max/1116/1*CRq9QlIpGlTx4-fQ2Hg73A.png" width="558" height="402" srcset="https://miro.medium.com/max/552/1*CRq9QlIpGlTx4-fQ2Hg73A.png 276w, https://miro.medium.com/max/1104/1*CRq9QlIpGlTx4-fQ2Hg73A.png 552w, https://miro.medium.com/max/1116/1*CRq9QlIpGlTx4-fQ2Hg73A.png 558w" sizes="558px" /></noscript>
</div>
</div>
</div>
<figcaption class="hf hg cz cx cy hh hi ce b eu cg ch" data-selectable-paragraph="">
Fig 2. Bounded context and microservices
</figcaption>
</figure>
<p id="0a1b" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Consider the example above. The Pricing bounded context has three distinct models — Price, Priced items, and Discounts, each responsible for the price of a catalog item, computing the total price of a list of items, and applying discounts respectively. We could create a single system that encompasses all the above models, but it could become an unreasonably large application. Each of the data models, as mentioned earlier, have their invariants and business rules. Over time, if we are not careful, the system could become a Big ball of mud with obscured boundaries, overlapping responsibilities, and probably back to where we started — a monolith.
</p>
<p id="a9ac" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Another way to model this system is to separate, or group related models into separate microservices. In DDD, these models — Price, Priced Items, and Discounts — are called <em class="jf">Aggregates</em>. An aggregate is a self-contained model that composes related models. You could change the state of an aggregate only through a published interface, and the aggregate ensures consistency and that the invariants hold good.
</p>
<p id="9e95" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Formally, An <em class="jf">Aggregate is a cluster of associated objects treated as a unit for data changes. External references are restricted to one member of the AGGREGATE, designated as the root. A set of consistency rules applies within the AGGREGATES boundaries.</em>
</p>
<figure class="gi gj gk gl gm gn cx cy paragraph-image">
<div class="cx cy ka">
<div class="gy s gq gz">
<div class="kb hb s">
<div class="gt gu t u v gv aj bk gw gx"></div><img alt="Image for post" class="tx ty t u v gv aj c" width="590" height="336" src="https://miro.medium.com/max/590/1*zDE5n8r9UoTy3EQ4C9C-3w.png" srcset="https://miro.medium.com/max/276/1*zDE5n8r9UoTy3EQ4C9C-3w.png 276w, https://miro.medium.com/max/552/1*zDE5n8r9UoTy3EQ4C9C-3w.png 552w, https://miro.medium.com/max/590/1*zDE5n8r9UoTy3EQ4C9C-3w.png 590w" sizes="590px" /><noscript><img alt="Image for post" class="t u v gv aj" src="https://miro.medium.com/max/1180/1*zDE5n8r9UoTy3EQ4C9C-3w.png" width="590" height="336" srcset="https://miro.medium.com/max/552/1*zDE5n8r9UoTy3EQ4C9C-3w.png 276w, https://miro.medium.com/max/1104/1*zDE5n8r9UoTy3EQ4C9C-3w.png 552w, https://miro.medium.com/max/1180/1*zDE5n8r9UoTy3EQ4C9C-3w.png 590w" sizes="590px" /></noscript>
</div>
</div>
</div>
<figcaption class="hf hg cz cx cy hh hi ce b eu cg ch" data-selectable-paragraph="">
Fig 3. Microservices in the Pricing Context
</figcaption>
</figure>
<p id="af8e" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Again, its not necessary to model every aggregate as a distinct microservice. It turned out to be so for the services (aggregates) in Fig 3, but thats not necessarily a rule. In some cases, it may make sense to host multiple aggregates in a single service, particularly when we dont fully understand the business domain. An important thing to note is that consistency can be guaranteed only within a single aggregate, and the aggregates can only be modified through the published interface. Any violation of these bears the risk of turning into a big ball of mud.
</p>
<h1 id="b6b3" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
<strong class="ay">Context maps — A way to carve out accurate microservice boundaries</strong>
</h1>
<p id="82b7" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
Another essential toolkit in your arsenal is the concept of Context maps — again, from Domain Driven Design. A monolith is usually composed of disparate models, mostly tightly coupled — models perhaps know the intimate details of one another, changing one could cause side effects on another, and so on. As you break down the monolith, its vital to identify these models — aggregates in this case — and their relationships. Context maps help us do just that. They are used to identify and define relationships between various bounded contexts and aggregates. While bounded contexts define the boundary of a model — Price, Discounts, etc. in the example above, Context maps define the relationships between these models and between different contexts. After identifying these dependencies, we can determine the right collaboration model between the teams that will implement these services.
</p>
<p id="13e8" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
A full exploration of Context maps is beyond the scope of this blog, but well illustrate it with an example. The below diagram represents the various applications that handle payments for an eCommerce order.
</p>
<ol class="">
<li id="cb4a" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd jl jm jn ek" data-selectable-paragraph="">The cart context takes care of online authorizations of an order; Order context processes post fulfillment payment processes like Settlements; Contact center handles any exceptions like retrying payments and changing the payment method used for the order
</li>
<li id="b779" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">For the sake of simplicity, lets assume that all these contexts are implemented as separate services
</li>
<li id="5f8a" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">All these contexts encapsulate the same model.
</li>
<li id="c7e9" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Note that these models are logically the same. That is, they all follow the same Ubiquitous domain language — payment methods, authorizations, and settlements. Just that they are a part of different contexts.
</li>
</ol>
<p id="9d96" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Another sign that the same model is spread around different contexts is that all of these integrate directly with a single payment gateway and do the same operations as one another
</p>
<figure class="gi gj gk gl gm gn cx cy paragraph-image">
<div role="button" tabindex="0" class="go gp gq gr aj gs">
<div class="cx cy kc">
<div class="gy s gq gz">
<div class="kd hb s">
<div class="gt gu t u v gv aj bk gw gx"></div><img alt="Image for post" class="tx ty t u v gv aj c" width="936" height="562" src="https://miro.medium.com/max/936/1*WJZqMtq1spHo6lghw3V_Uw.png" srcset="https://miro.medium.com/max/276/1*WJZqMtq1spHo6lghw3V_Uw.png 276w, https://miro.medium.com/max/552/1*WJZqMtq1spHo6lghw3V_Uw.png 552w, https://miro.medium.com/max/640/1*WJZqMtq1spHo6lghw3V_Uw.png 640w, https://miro.medium.com/max/700/1*WJZqMtq1spHo6lghw3V_Uw.png 700w" sizes="700px" /><noscript><img alt="Image for post" class="t u v gv aj" src="https://miro.medium.com/max/1872/1*WJZqMtq1spHo6lghw3V_Uw.png" width="936" height="562" srcset="https://miro.medium.com/max/552/1*WJZqMtq1spHo6lghw3V_Uw.png 276w, https://miro.medium.com/max/1104/1*WJZqMtq1spHo6lghw3V_Uw.png 552w, https://miro.medium.com/max/1280/1*WJZqMtq1spHo6lghw3V_Uw.png 640w, https://miro.medium.com/max/1400/1*WJZqMtq1spHo6lghw3V_Uw.png 700w" sizes="700px" /></noscript>
</div>
</div>
</div>
</div>
<figcaption class="hf hg cz cx cy hh hi ce b eu cg ch" data-selectable-paragraph="">
Fig 4. An incorrectly defined context map
</figcaption>
</figure>
<h1 id="974f" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
<strong class="ay">Redefining the service boundaries — Map the aggregates to the right contexts</strong>
</h1>
<p id="2407" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
There are a few problems that are very evident in the above design (Fig 4). Payments aggregate is part of multiple contexts. Its impossible to enforce invariants and consistency across various services, not to mention the concurrency issues between these services. For example, what happens if the contact center changes the payment method associated with the order while the Orders service is trying to post settlement of a previously submitted payment method. Also, note that any change in the payment gateway would force changes to multiple services and potentially numerous teams, as different groups could own these contexts.
</p>
<p id="9449" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
With a few adjustments and aligning the aggregates to the right contexts, we get a much better representation of these subdomains — Fig 5. There is a lot that has changed. Lets review the changes:
</p>
<ol class="">
<li id="42ee" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd jl jm jn ek" data-selectable-paragraph="">Payments aggregate has a new home — Payment service. This service also abstracts the Payment gateway from the other services that require payment services. As a single bounded context now owns an aggregate, the invariants are easy to manage; all transactions happen within the same service boundary helping to avoid any concurrency issues.
</li>
<li id="f9b6" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Payments aggregate uses an Anti-corruption Layer (ACL) to isolate the core domain model from the payment gateways data model, which is usually a third-party provider and perhaps bound to change. Well dive deeper into the application design of such as service using Ports and Adapters pattern in a future post. The ACL layer usually contains the adapters that transform the data model of the payment gateway to the Payments aggregate data model.
</li>
<li id="ba20" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Cart service calls the Payments service through direct API calls as the cart service may have to complete the payment authorization while the customers are on the website
</li>
<li id="f7ad" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Make a note of the interaction between Orders and Payment service. Orders service emits a domain event (more on this later in this blog). Payments service listens to this event and completes settlement of the order
</li>
<li id="3dbe" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Contact center service may have many aggregates, but we are only interested in the Orders aggregate for this use case. This service emits an event when the payment method changes, and the Payments service reacts to it by reversing the credit card used prior and processing the new credit card.
</li>
</ol>
<figure class="gi gj gk gl gm gn cx cy paragraph-image">
<div role="button" tabindex="0" class="go gp gq gr aj gs">
<div class="cx cy ke">
<div class="gy s gq gz">
<div class="kf hb s">
<div class="gt gu t u v gv aj bk gw gx"></div><img alt="Image for post" class="tx ty t u v gv aj c" width="742" height="726" src="https://miro.medium.com/max/742/1*6jb1gyx5KK9q0cV1x5t2eA.png" srcset="https://miro.medium.com/max/276/1*6jb1gyx5KK9q0cV1x5t2eA.png 276w, https://miro.medium.com/max/552/1*6jb1gyx5KK9q0cV1x5t2eA.png 552w, https://miro.medium.com/max/640/1*6jb1gyx5KK9q0cV1x5t2eA.png 640w, https://miro.medium.com/max/700/1*6jb1gyx5KK9q0cV1x5t2eA.png 700w" sizes="700px" /><noscript><img alt="Image for post" class="t u v gv aj" src="https://miro.medium.com/max/1484/1*6jb1gyx5KK9q0cV1x5t2eA.png" width="742" height="726" srcset="https://miro.medium.com/max/552/1*6jb1gyx5KK9q0cV1x5t2eA.png 276w, https://miro.medium.com/max/1104/1*6jb1gyx5KK9q0cV1x5t2eA.png 552w, https://miro.medium.com/max/1280/1*6jb1gyx5KK9q0cV1x5t2eA.png 640w, https://miro.medium.com/max/1400/1*6jb1gyx5KK9q0cV1x5t2eA.png 700w" sizes="700px" /></noscript>
</div>
</div>
</div>
</div>
<figcaption class="hf hg cz cx cy hh hi ce b eu cg ch" data-selectable-paragraph="">
Fig 5. Redefined context map
</figcaption>
</figure>
<p id="2d18" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Usually, a monolithic or a legacy application has many aggregates, often with overlapping boundaries. Creating a context map of these aggregates and their dependencies helps us understand the contours of any new microservices that we will wrest out of these monoliths. Remember, the success or failure of microservices architecture hinges upon low coupling between the aggregates and high cohesion within these aggregates.
</p>
<p id="cdc0" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Its also important to note that bounded contexts are themselves suitable cohesive units. Even if a context has multiple aggregates, the entire context, along with its aggregates, can be composed into a single microservice. We find this heuristic particularly useful for domains that are a bit obscure — think about a new line of business the organization is venturing into. You may not have sufficient insight into the right boundaries of separation, and any premature decomposition of aggregates can lead to expensive refactoring. Imagine having to merge two databases into one, along with data migration, because we happened to find that two aggregates belong together. But ensure these aggregates are sufficiently isolated through interfaces so that they dont know the intricate details of one another.
</p>
<h1 id="c868" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
<strong class="ay">Event Storming — Another technique to identify service boundaries</strong>
</h1>
<p id="a5e7" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
Event Storming is another essential technique to identify aggregates (and hence microservices) in a system. It is a useful tool both for breaking monoliths and when designing a complex ecosystem of microservices. We have used this technique to break down one of our complex applications, and we intend to cover our experiences with Event Storming in a separate blog. For the scope of this blog, we want to give a quick high-level overview. Please watch <a href="https://www.youtube.com/watch?v=1i6QYvYhlYQ" class="ck hj" rel="noopener nofollow">Alberto Brandellonis video</a> on the topic if you are interested in exploring further.
</p>
<p id="ef88" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
In a nutshell, Event Storming is a brainstorming exercise between the teams that work on an application — in our case, a monolith — to identify the various domain events and processes that happen within a system. The teams also identify the aggregates or models these events affect and any subsequent impacts thereof. As the teams do this exercise, they identify different overlapping concepts, ambiguous domain language, and conflicting business processes. They group related models, redefine aggregates and identify duplicate processes. As they progress with this exercise, the bounded contexts where these aggregates belong becomes clear. Event Storming workshops are useful if all the teams are in a single room — physical or virtual — and start to map the events, commands, and processes on a scrum-style whiteboard. At the end of this exercise, below are the usual outcomes:
</p>
<ol class="">
<li id="eb62" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd jl jm jn ek" data-selectable-paragraph="">Redefined list of Aggregates. These potentially become new microservices
</li>
<li id="7d76" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Domain Events that need to flow between these microservices
</li>
<li id="47d3" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Commands which are direct invocations from other applications or users
</li>
</ol>
<p id="4598" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Weve shown a sample board at the end of an Event Storming workshop below. Its a great collaborative exercise for the teams to agree on the right aggregates and bounded contexts. Besides being a great team-building exercise, the teams come out of this session with a shared understanding of the domain, ubiquitous language, and precise service boundaries.
</p>
<figure class="gi gj gk gl gm gn cx cy paragraph-image">
<div role="button" tabindex="0" class="go gp gq gr aj gs">
<div class="cx cy kc">
<div class="gy s gq gz">
<div class="kg hb s">
<div class="gt gu t u v gv aj bk gw gx"></div><img alt="Image for post" class="tx ty t u v gv aj c" width="936" height="406" src="https://miro.medium.com/max/936/1*CL-6_jfymabIiv1NI_5epg.png" srcset="https://miro.medium.com/max/276/1*CL-6_jfymabIiv1NI_5epg.png 276w, https://miro.medium.com/max/552/1*CL-6_jfymabIiv1NI_5epg.png 552w, https://miro.medium.com/max/640/1*CL-6_jfymabIiv1NI_5epg.png 640w, https://miro.medium.com/max/700/1*CL-6_jfymabIiv1NI_5epg.png 700w" sizes="700px" /><noscript><img alt="Image for post" class="t u v gv aj" src="https://miro.medium.com/max/1872/1*CL-6_jfymabIiv1NI_5epg.png" width="936" height="406" srcset="https://miro.medium.com/max/552/1*CL-6_jfymabIiv1NI_5epg.png 276w, https://miro.medium.com/max/1104/1*CL-6_jfymabIiv1NI_5epg.png 552w, https://miro.medium.com/max/1280/1*CL-6_jfymabIiv1NI_5epg.png 640w, https://miro.medium.com/max/1400/1*CL-6_jfymabIiv1NI_5epg.png 700w" sizes="700px" /></noscript>
</div>
</div>
</div>
</div>
<figcaption class="hf hg cz cx cy hh hi ce b eu cg ch" data-selectable-paragraph="">
Fig 6. Event Storming board
</figcaption>
</figure>
<h1 id="9bb1" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
<strong class="ay">Communication between microservices</strong>
</h1>
<p id="7e84" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
To quickly recap, a monolith hosts multiple aggregates within a single process boundary. Hence managing consistency of aggregates within this boundary is possible. For example, if a Customer places an Order, we can decrement the Inventory of the items, send an email to the Customer — all within a single transaction. All operations would succeed, or all would fail. But, as we break the monolith and spread the aggregates into different contexts, we will have tens or even hundreds of microservices. The processes that hitherto existed within the single boundary of a monolith is now spread across multiple distributed systems. Achieving transactional integrity and consistency across all of these distributed systems is very hard, and it comes at a cost — the availability of the systems.
</p>
<p id="b28d" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Microservices are distributed-systems as well. Hence, CAP theorem applies to them as well — <em class="jf">“a distributed system can deliver only two of three desired characteristics: consistency, availability, and partition tolerance (the C, A and P in CAP).”</em> In real-world systems, partition tolerance is not negotiable — <a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing" class="ck hj" rel="noopener nofollow">network is unreliable</a>, virtual machines can go down, latency between regions can become worse, and so on.
</p>
<p id="2058" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
So that leaves us with a choice of either Availability or Consistency. Now, we know that in any modern application, sacrificing availability is not a good idea either.
</p>
<figure class="gi gj gk gl gm gn cx cy paragraph-image">
<div class="cx cy kh">
<div class="gy s gq gz">
<div class="ki hb s">
<div class="gt gu t u v gv aj bk gw gx"></div><img alt="Image for post" class="tx ty t u v gv aj c" width="206" height="196" src="https://miro.medium.com/max/206/1*h-XBZDSgZfCpXMfDtw8EYQ.png" srcset="" sizes="206px" /><noscript><img alt="Image for post" class="t u v gv aj" src="https://miro.medium.com/max/412/1*h-XBZDSgZfCpXMfDtw8EYQ.png" width="206" height="196" /></noscript>
</div>
</div>
</div>
<figcaption class="hf hg cz cx cy hh hi ce b eu cg ch" data-selectable-paragraph="">
Fig 7. CAP Theorem
</figcaption>
</figure>
<h1 id="54e5" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
Design applications around eventual consistency
</h1>
<p id="cf43" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
If you try to build transactions across several distributed systems, youll end up in the monolith land again. Only this time it will be the worst kind, a distributed monolith. If any of the systems become unavailable, the whole process becomes unavailable, often leading to frustrating customer experience, failed promises, and so on. Besides, changes to one service may usually entail changes to another service, leading to complex and costly deployments. Hence, we are better off designing applications tailoring our use cases to tolerate a little bit of inconsistency in favor of availability. For the example above, we can make all the processes asynchronous and hence eventually consistent. We can send emails asynchronously, independent of the other processes; If an item thats promised is not available in the warehouse later, the item could be back-ordered, or we could stop taking orders for the item beyond a certain threshold.<br />
Occasionally, you may encounter a scenario that might require strong ACID-style transactions across two aggregates in different process boundaries. Thats an excellent sign to revisit these aggregates and perhaps combine them into one. Event Storming and Context Maps will help identify these dependencies early on before we start breaking up these aggregates in different process boundaries. Merging two microservices into one is costly, and thats something we should strive to avoid.
</p>
<h1 id="0aaa" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
Favor event-driven architecture
</h1>
<p id="81f1" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
Microservices can emit essential changes that happen to their aggregates. These are called Domain events, and any services that are interested in these changes can listen to these events and take respective action within their domains. This method avoids any behavioral coupling — one domain doesnt prescribe what the other domains should do, and temporal coupling — the successful completion of a process doesnt depend on all the systems to be available at the same time. This, of course, will mean that the systems will be eventually consistent.
</p>
<figure class="gi gj gk gl gm gn cx cy paragraph-image">
<div class="cx cy kj">
<div class="gy s gq gz">
<div class="kk hb s">
<div class="gt gu t u v gv aj bk gw gx"></div><img alt="Image for post" class="tx ty t u v gv aj c" width="686" height="580" src="https://miro.medium.com/max/686/1*7KRwNMvjysqKEEBmdm4jmw.png" srcset="https://miro.medium.com/max/276/1*7KRwNMvjysqKEEBmdm4jmw.png 276w, https://miro.medium.com/max/552/1*7KRwNMvjysqKEEBmdm4jmw.png 552w, https://miro.medium.com/max/640/1*7KRwNMvjysqKEEBmdm4jmw.png 640w, https://miro.medium.com/max/686/1*7KRwNMvjysqKEEBmdm4jmw.png 686w" sizes="686px" /><noscript><img alt="Image for post" class="t u v gv aj" src="https://miro.medium.com/max/1372/1*7KRwNMvjysqKEEBmdm4jmw.png" width="686" height="580" srcset="https://miro.medium.com/max/552/1*7KRwNMvjysqKEEBmdm4jmw.png 276w, https://miro.medium.com/max/1104/1*7KRwNMvjysqKEEBmdm4jmw.png 552w, https://miro.medium.com/max/1280/1*7KRwNMvjysqKEEBmdm4jmw.png 640w, https://miro.medium.com/max/1372/1*7KRwNMvjysqKEEBmdm4jmw.png 686w" sizes="686px" /></noscript>
</div>
</div>
</div>
<figcaption class="hf hg cz cx cy hh hi ce b eu cg ch" data-selectable-paragraph="">
Fig 8. Event driven architecture
</figcaption>
</figure>
<p id="cb94" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
In the example above, Orders service publishes an event — Order Cancelled. The other services that have subscribed to the event process their respective domain functions: Payment service refunds the money, Inventory service adjusts the inventory of the items, and so on. Few things to note to ensure the reliability and resiliency of this integration:
</p>
<ol class="">
<li id="4d94" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd jl jm jn ek" data-selectable-paragraph="">Producers should ensure that they produce an event at least once. If there are failures in doing so, they should ensure there is a fall back mechanism present to re-trigger the events
</li>
<li id="3790" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Consumers should ensure that they consume the events in an idempotent way. If the same event occurs again, there shouldnt be any side effect at the consumer end. Events may also arrive out of sequence. Consumers can use Timestamp or version numbers fields to guarantee the uniqueness of the events.
</li>
</ol>
<p id="ebe5" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
It may not always be possible to use event-based integration due to the nature of some use cases. Please take a look at the integration between the Cart service and Payment service. Its a synchronous integration, and hence has a few things we should watch out. Its an example of behavioral coupling — Cart service perhaps calls a REST API from Payment service and instructs it to authorize the payment for an order, and temporal coupling — Payment service needs to be available for Cart service to accept an order. This kind of coupling reduces the autonomy of these contexts and maybe an undesirable dependency. There are a few ways to avoid this coupling, but with all these options, we will lose the ability to provide instant feedback to the customers.
</p>
<ol class="">
<li id="73b7" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd jl jm jn ek" data-selectable-paragraph="">Convert the REST API to an event-based integration. But this option may not be available if the Payment Service exposes only a REST API
</li>
<li id="035d" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Cart service accepts an order instantaneously, and there is a batch job which picks up the orders and calls the Payment service API
</li>
<li id="6768" class="ii ij dn ik b il jo hp in io jp ht iq ir jq it iu iv jr ix iy iz js jb jc jd jl jm jn ek" data-selectable-paragraph="">Cart service produces a local event which then calls the Payment service API
</li>
</ol>
<p id="469e" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
A combination of the above with retries in case of failures and unavailability of the upstream dependency — Payment service — can result in a much more resilient design. For example, the synchronous integration between the Cart and the Payment services can be backed up by an event or batch-based retries in cases of failures. This approach has an added impact on the customer experience — the customers may have entered incorrect payment details, and we will not have them online when we process the payments offline. Or there may be an added cost to the business to reclaim failed payments. But in all likelihood, the benefits of the Cart service being resilient to the Payment services unavailability or faults outweigh the shortcomings. For example, we can notify the customers if we are not able to collect payments offline. In short, there are trade-offs between user experience, resiliency, and operating costs, and its wise to design systems, keeping these compromises in mind.
</p>
<h1 id="1ad1" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
Avoid orchestration between services for consumer-specific data needs
</h1>
<p id="7077" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
One of the anti-patterns in any service-oriented architecture is that the services cater to the specific access patterns of consumers. Usually, this happens when the consumer teams work closely with the service teams. If the team was working on a monolithic application, they would often create a single API that crosses different aggregate boundaries, hence tightly coupling these aggregates. Lets consider an example. Say the Order Details page in Web, and Mobile applications need to show the details of both an Order and the details of the refunds processed for the order on a single page. In a monolithic application, an Order GET API — assuming its REST API — queries Orders and Refunds together, consolidates both the aggregates and sends a composite response to the callers. Its possible to do this without a lot of overhead as the aggregates belong to the same process boundary. Thus, consumers can get all the necessary data in a single call.
</p>
<p id="01c7" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
If Orders and Refunds are part of different contexts, the data is no longer present within a single microservice or aggregate boundary. One option to retain the same functionality for the consumers is by making Order service responsible for calling the Refunds service and create a composite response. This approach causes several concerns:
</p>
<p id="97e9" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
1. Order service now integrates with another service purely for supporting the consumers who need the Refund data along with Order data. Order service is less autonomous now as any changes in Refunds aggregate will lead to a change to the Order aggregate.
</p>
<p id="2a4f" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
2. Order service has another integration and hence another failure point to take into account — if Refunds service is down, can Order Service still send partial data, and can the consumers fail gracefully?
</p>
<p id="0d74" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
3. If the consumers need a change to fetch more data from the Refunds aggregate, two teams are involved now to make this change
</p>
<p id="fe23" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
4. This pattern, if followed across the platform, can lead to an intricate web of dependencies between the various domain services, all because these services cater to the callers specific access patterns.
</p>
<h1 id="74fc" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
Backend for Frontends (BFFs)
</h1>
<p id="a394" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
An approach to mitigate this risk is to let the consumer teams manage the orchestration between the various domain services. After all, the callers know the access patterns better and can be in complete control of any changes to these patterns. This approach decouples the domain services from the presentation tier, letting them focus on the core business processes. But if the web and mobile apps begin to call different services directly instead of the one composite API from the monolith, it may cause performance overhead to these apps — multiple calls over lower bandwidth networks, processing and merging data from different APIs, and so on.
</p>
<p id="a2a4" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Instead, one could use another pattern called <a href="https://www.boldare.com/blog/event-storming-guide/Backend%20for%20Frontends%E2%80%8A-%E2%80%8Ahttps://www.thoughtworks.com/insights/blog/bff-soundcloud" class="ck hj" rel="noopener nofollow">Backend for Front-ends</a>. In this design pattern, a backend service created and managed by the consumers — in this case, the web and mobile teams — takes care of integration across multiple domain services purely to render the front-end experience to the customers. The web and mobile teams can now design the data contracts based on the use cases that they cater to. They can even use GraphQL instead of REST APIs to flexibly query and get back exactly what they need. Its important to note that this service is owned and maintained by the consumer teams and not by the teams that own the domain services. The front-end teams can now optimize based on their needs — a mobile app can request a smaller payload, reduce the number of calls from the mobile app, and so on. Take a look at the revised view of the orchestration below. The BFF service now calls both Orders and Refunds domain services for its use case.
</p>
<figure class="gi gj gk gl gm gn cx cy paragraph-image">
<div class="cx cy kl">
<div class="gy s gq gz">
<div class="km hb s">
<div class="gt gu t u v gv aj bk gw gx"></div><img alt="Image for post" class="tx ty t u v gv aj c" width="560" height="388" src="https://miro.medium.com/max/560/1*CcRBzPfaGd7gs8gBXGr7BA.png" srcset="https://miro.medium.com/max/276/1*CcRBzPfaGd7gs8gBXGr7BA.png 276w, https://miro.medium.com/max/552/1*CcRBzPfaGd7gs8gBXGr7BA.png 552w, https://miro.medium.com/max/560/1*CcRBzPfaGd7gs8gBXGr7BA.png 560w" sizes="560px" /><noscript><img alt="Image for post" class="t u v gv aj" src="https://miro.medium.com/max/1120/1*CcRBzPfaGd7gs8gBXGr7BA.png" width="560" height="388" srcset="https://miro.medium.com/max/552/1*CcRBzPfaGd7gs8gBXGr7BA.png 276w, https://miro.medium.com/max/1104/1*CcRBzPfaGd7gs8gBXGr7BA.png 552w, https://miro.medium.com/max/1120/1*CcRBzPfaGd7gs8gBXGr7BA.png 560w" sizes="560px" /></noscript>
</div>
</div>
</div>
<figcaption class="hf hg cz cx cy hh hi ce b eu cg ch" data-selectable-paragraph="">
Fig 9. Backend for Frontends
</figcaption>
</figure>
<p id="4da9" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
Its also useful to build the BFF service early on, before breaking a plethora of services from the monolith. Otherwise, either the domain services will have to support the inter-domain orchestration, or the web and mobile apps will have to call multiple services directly from the front-end. Both of these options will lead to performance overhead, throw-away work, and lack of autonomy between the teams.
</p>
<h1 id="6613" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
Conclusion
</h1>
<p id="161c" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
In this blog, we touched upon various concepts, strategies, and design heuristics to consider when we venture into the world of microservices, more specifically when we try to break a monolith into multiple domain-based microservices. Many of these are vast topics on their own, and I dont think weve done enough justice to explain them in full detail, but we wanted to introduce some of the critical topics and our experience in adopting these. Further Reading (link) section has some references and some useful content for anyone who wishes to pursue this path.
</p>
<p id="fe5f" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
<strong class="ik je">Update:</strong> The next two blogs in the series are out. These two blogs discuss implementing the Cart microservice, with code examples, using Domain-Driven Design principles, and Ports and Adapters design patterns. The primary focus of these blogs is to demonstrate how these two principles/patterns help us build modular applications that are agile, testable, and refactorable — in short, be able to respond to the fast-paced environment we are all operating on.
</p>
<p id="42cb" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
<a class="ck hj" rel="noopener" href="/walmartglobaltech/implementing-cart-service-with-ddd-hexagonal-port-adapter-architecture-part-1-4dab93b3fa9f">Implementing Cart Microservice using Domain Driven Design and Ports and Adapters Pattern — Part 1</a>
</p>
<p id="c811" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
<a class="ck hj" rel="noopener" href="/walmartglobaltech/implementing-cart-service-with-ddd-hexagonal-port-adapter-architecture-part-2-d9c00e290ab">Implementing Cart Microservice using Domain Driven Design and Ports and Adapters Pattern — Part 2</a>
</p>
<h1 id="e088" class="hk hl dn ce hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie if ig ih ek" data-selectable-paragraph="">
Further Reading
</h1>
<p id="fc9c" class="ii ij dn ik b il im hp in io ip ht iq ir is it iu iv iw ix iy iz ja jb jc jd df ek" data-selectable-paragraph="">
1. <a href="https://www.walmart.com/ip/Domain-Driven-Design-Tackling-Complexity-in-the-Heart-of-Software-Hardcover-9780321125217/2222375" class="ck hj" rel="noopener nofollow">Eric Evans Domain Driven Design</a>
</p>
<p id="80d6" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
2. <a href="https://www.walmart.com/ip/Implementing-Domain-Driven-Design-Hardcover-9780321834577/21124187" class="ck hj" rel="noopener nofollow">Vaughn Vernons Implementing Domain Driven Design</a>
</p>
<p id="708a" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
3. <a href="https://martinfowler.com/articles/microservices.html" class="ck hj" rel="noopener nofollow">Martin Fowlers article on Microservices</a>
</p>
<p id="abcc" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
4. <a href="https://www.walmart.com/ip/Building-Microservices-Designing-Fine-Grained-Systems-9781491950357/40970629" class="ck hj" rel="noopener nofollow">Sam Newmans Building Microservices</a>
</p>
<p id="f1e5" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
5. <a href="https://www.youtube.com/watch?v=1i6QYvYhlYQ" class="ck hj" rel="noopener nofollow">Event storming</a>
</p>
<p id="cf91" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
7. <a href="https://www.thoughtworks.com/insights/blog/bff-soundcloud" class="ck hj" rel="noopener nofollow">Backend for Frontends</a>
</p>
<p id="1113" class="ii ij dn ik b il jg hp in io jh ht iq ir ji it iu iv jj ix iy iz jk jb jc jd df ek" data-selectable-paragraph="">
<a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing" class="ck hj" rel="noopener nofollow">8.</a> <a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing" class="ck hj" rel="noopener nofollow">Fallacies of distributed computing</a>
</p>
</div>
</div>
</section>
</div>
</article>
<div class="gt de ko kn aj uc kt kw" data-test-id="post-sidebar">
<div class="n p">
<div class="ab ac ae af ag ah ai aj">
<div class="kx n ky">
<div class="de">
<div>
<div class="la lb s">
<a href="/walmartglobaltech?source=post_sidebar--------------------------post_sidebar-----------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">
<h2 class="ce hm kz cg dm ek df">
Walmart Global Tech Blog
</h2></a>
<div class="lc ld s">
<p class="ce b eu cg bk le ey ez lf fb fc ch">
Were powering the next great retail disruption.
</p>
</div>
<div class="ft" aria-hidden="false" aria-describedby="collectionFollowPopover" aria-labelledby="collectionFollowPopover">
<div class="n lh">
<span><button class="ce b eu cg ff lg fh fi fj fk fl bb fm fn fo fp fq fr fs da ft fu">Follow</button></span>
</div>
</div>
</div>
<div class="li lj lk n">
<div class="n o">
<div class="s gq ll lm ln lo lp">
<span><a href="https://medium.com/m/signin?actionUrl=%2F_%2Fvote%2Fwalmartglobaltech%2Faf688aa1b1b8&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fwalmartglobaltech%2Fbuilding-domain-driven-microservices-af688aa1b1b8&amp;source=post_sidebar-----af688aa1b1b8---------------------clap_sidebar-----------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">
<div class="az lq lr ls lt lu lv lw r lx ly">
<span><svg width="29" height="29" aria-label="clap">
<g fill-rule="evenodd">
<path d="M13.74 1l.76 2.97.76-2.97zM16.82 4.78l1.84-2.56-1.43-.47zM10.38 2.22l1.84 2.56-.41-3.03zM22.38 22.62a5.11 5.11 0 0 1-3.16 1.61l.49-.45c2.88-2.89 3.45-5.98 1.69-9.21l-1.1-1.94-.96-2.02c-.31-.67-.23-1.18.25-1.55a.84.84 0 0 1 .66-.16c.34.05.66.28.88.6l2.85 5.02c1.18 1.97 1.38 5.12-1.6 8.1M9.1 22.1l-5.02-5.02a1 1 0 0 1 .7-1.7 1 1 0 0 1 .72.3l2.6 2.6a.44.44 0 0 0 .63-.62L6.1 15.04l-1.75-1.75a1 1 0 1 1 1.41-1.41l4.15 4.15a.44.44 0 0 0 .63 0 .44.44 0 0 0 0-.62L6.4 11.26l-1.18-1.18a1 1 0 0 1 0-1.4 1.02 1.02 0 0 1 1.41 0l1.18 1.16L11.96 14a.44.44 0 0 0 .62 0 .44.44 0 0 0 0-.63L8.43 9.22a.99.99 0 0 1-.3-.7.99.99 0 0 1 .3-.7 1 1 0 0 1 1.41 0l7 6.98a.44.44 0 0 0 .7-.5l-1.35-2.85c-.31-.68-.23-1.19.25-1.56a.85.85 0 0 1 .66-.16c.34.06.66.28.88.6L20.63 15c1.57 2.88 1.07 5.54-1.55 8.16a5.62 5.62 0 0 1-5.06 1.65 9.35 9.35 0 0 1-4.93-2.72zM13 6.98l2.56 2.56c-.5.6-.56 1.41-.15 2.28l.26.56-4.25-4.25a.98.98 0 0 1-.12-.45 1 1 0 0 1 .29-.7 1.02 1.02 0 0 1 1.41 0zm8.89 2.06c-.38-.56-.9-.92-1.49-1.01a1.74 1.74 0 0 0-1.34.33c-.38.29-.61.65-.71 1.06a2.1 2.1 0 0 0-1.1-.56 1.78 1.78 0 0 0-.99.13l-2.64-2.64a1.88 1.88 0 0 0-2.65 0 1.86 1.86 0 0 0-.48.85 1.89 1.89 0 0 0-2.67-.01 1.87 1.87 0 0 0-.5.9c-.76-.75-2-.75-2.7-.04a1.88 1.88 0 0 0 0 2.66c-.3.12-.61.29-.87.55a1.88 1.88 0 0 0 0 2.66l.62.62a1.88 1.88 0 0 0-.9 3.16l5.01 5.02c1.6 1.6 3.52 2.64 5.4 2.96a7.16 7.16 0 0 0 1.18.1c1.03 0 2-.25 2.9-.7A5.9 5.9 0 0 0 23 23.24c3.34-3.34 3.08-6.93 1.74-9.17l-2.87-5.04z"></path>
</g></svg></span>
</div></a></span>
</div>
<div class="s lz ma mb mc md me mf">
<div class="mg">
<p class="ce b eu cg ch">
<button class="ck cl au av aw ax ay az ba bb cm cn be co cp">641</button>
</p>
</div>
</div>
</div>
</div>
<div class="lj s">
<div class="mj n o lh">
<button class="lt lr az"><svg width="25" height="25" class="r" aria-label="responses">
<path d="M19.07 21.12a6.33 6.33 0 0 1-3.53-1.1 7.8 7.8 0 0 1-.7-.52c-.77.21-1.57.32-2.38.32-4.67 0-8.46-3.5-8.46-7.8C4 7.7 7.79 4.2 12.46 4.2c4.66 0 8.46 3.5 8.46 7.8 0 2.06-.85 3.99-2.4 5.45a6.28 6.28 0 0 0 1.14 2.59c.15.21.17.48.06.7a.69.69 0 0 1-.62.38h-.03zm0-1v.5l.03-.5h-.03zm-3.92-1.64l.21.2a6.09 6.09 0 0 0 3.24 1.54 7.14 7.14 0 0 1-.83-1.84 5.15 5.15 0 0 1-.16-.75 2.4 2.4 0 0 1-.02-.29v-.23l.18-.15a6.6 6.6 0 0 0 2.3-4.96c0-3.82-3.4-6.93-7.6-6.93-4.19 0-7.6 3.11-7.6 6.93 0 3.83 3.41 6.94 7.6 6.94.83 0 1.64-.12 2.41-.35l.28-.08z" fill-rule="evenodd"></path></svg></button>
<div class="s gq mk ml mm mn mo mp mq mr">
<p class="ce b eu cg ch">
<button class="lt lr az">5<!-- --></button>
</p>
</div>
</div>
</div>
<div class="ge">
<span><a href="https://medium.com/m/signin?actionUrl=%2F_%2Fbookmark%2Fp%2Faf688aa1b1b8&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fwalmartglobaltech%2Fbuilding-domain-driven-microservices-af688aa1b1b8&amp;source=post_sidebar-----af688aa1b1b8---------------------bookmark_sidebar-----------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener"><svg width="25" height="25" viewbox="0 0 25 25">
<path d="M19 6a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v14.66h.01c.01.1.05.2.12.28a.5.5 0 0 0 .7.03l5.67-4.12 5.66 4.13a.5.5 0 0 0 .71-.03.5.5 0 0 0 .12-.29H19V6zm-6.84 9.97L7 19.64V6a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v13.64l-5.16-3.67a.49.49 0 0 0-.68 0z" fill-rule="evenodd"></path></svg></a></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="gt de kn ko kp kq kr ks kt ku"></div>
<div>
<div class="ms gn n ky p">
<div class="n p">
<div class="ab ac ae af ag dk ai aj">
<div class="n mt"></div>
<div class="n o mt"></div>
<div class="mu s">
<ul class="az ba">
<li class="ft bq gf mv">
<a href="https://medium.com/walmartglobaltech/tagged/microservices" class="ce b cf mw ch mx my fu s mz">Microservices</a>
</li>
<li class="ft bq gf mv">
<a href="https://medium.com/walmartglobaltech/tagged/distributed-systems" class="ce b cf mw ch mx my fu s mz">Distributed Systems</a>
</li>
<li class="ft bq gf mv">
<a href="https://medium.com/walmartglobaltech/tagged/domain-driven-design" class="ce b cf mw ch mx my fu s mz">Domain Driven Design</a>
</li>
<li class="ft bq gf mv">
<a href="https://medium.com/walmartglobaltech/tagged/bounded-context" class="ce b cf mw ch mx my fu s mz">Bounded Context</a>
</li>
</ul>
</div>
<div class="mu n em z">
<div class="n lh">
<div class="na s">
<div class="n o">
<div class="s gq ll lm ln lo lp">
<span class="s nb nc nd e d"><span><a href="https://medium.com/m/signin?actionUrl=%2F_%2Fvote%2Fwalmartglobaltech%2Faf688aa1b1b8&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fwalmartglobaltech%2Fbuilding-domain-driven-microservices-af688aa1b1b8&amp;source=post_actions_footer-----af688aa1b1b8---------------------clap_footer-----------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">
<div class="az lq lr ls lt lu lv lw r lx ly">
<span class="s nb nc nd e d"><svg width="25" height="25" viewbox="0 0 25 25" aria-label="clap">
<g fill-rule="evenodd">
<path d="M11.74 0l.76 2.97.76-2.97zM14.81 3.78l1.84-2.56-1.42-.47zM8.38 1.22l1.84 2.56L9.8.75zM20.38 21.62a5.11 5.11 0 0 1-3.16 1.61l.49-.45c2.88-2.89 3.45-5.98 1.69-9.21l-1.1-1.94-.96-2.02c-.31-.67-.23-1.18.25-1.55a.84.84 0 0 1 .66-.16c.34.05.66.28.88.6l2.85 5.02c1.18 1.97 1.38 5.12-1.6 8.1M7.1 21.1l-5.02-5.02a1 1 0 0 1 .7-1.7 1 1 0 0 1 .72.3l2.6 2.6a.44.44 0 0 0 .63-.62L4.1 14.04l-1.75-1.75a1 1 0 1 1 1.41-1.41l4.15 4.15a.44.44 0 0 0 .63 0 .44.44 0 0 0 0-.62L4.4 10.26 3.22 9.08a1 1 0 0 1 0-1.4 1.02 1.02 0 0 1 1.41 0l1.18 1.16L9.96 13a.44.44 0 0 0 .62 0 .44.44 0 0 0 0-.63L6.43 8.22a.99.99 0 0 1-.3-.7.99.99 0 0 1 .3-.7 1 1 0 0 1 1.41 0l7 6.98a.44.44 0 0 0 .7-.5l-1.35-2.85c-.31-.68-.23-1.19.25-1.56a.85.85 0 0 1 .66-.16c.34.06.66.28.88.6L18.63 14c1.57 2.88 1.07 5.54-1.55 8.16a5.62 5.62 0 0 1-5.06 1.65 9.35 9.35 0 0 1-4.93-2.72zM11 5.98l2.56 2.56c-.5.6-.56 1.41-.15 2.28l.26.56-4.25-4.25a.98.98 0 0 1-.12-.45 1 1 0 0 1 .29-.7 1.02 1.02 0 0 1 1.41 0zm8.89 2.06c-.38-.56-.9-.92-1.49-1.01a1.74 1.74 0 0 0-1.34.33c-.38.29-.61.65-.71 1.06a2.1 2.1 0 0 0-1.1-.56 1.78 1.78 0 0 0-.99.13l-2.64-2.64a1.88 1.88 0 0 0-2.65 0 1.86 1.86 0 0 0-.48.85 1.89 1.89 0 0 0-2.67-.01 1.87 1.87 0 0 0-.5.9c-.76-.75-2-.75-2.7-.04a1.88 1.88 0 0 0 0 2.66c-.3.12-.61.29-.87.55a1.88 1.88 0 0 0 0 2.66l.62.62a1.88 1.88 0 0 0-.9 3.16l5.01 5.02c1.6 1.6 3.52 2.64 5.4 2.96a7.16 7.16 0 0 0 1.18.1c1.03 0 2-.25 2.9-.7A5.9 5.9 0 0 0 21 22.24c3.34-3.34 3.08-6.93 1.74-9.17l-2.87-5.04z"></path>
</g></svg></span>
</div></a></span></span>
</div>
<div class="s lz ma mb mc md me mf">
<div class="gq ne mg">
<p class="ce b eu cg ek">
<button class="ck cl au av aw ax ay az ba bb cm cn be co cp">641<span class="s h g f nf ng">&#160;claps</span></button>
</p>
</div>
</div>
</div>
<div class="n bu">
<div class="s gq ll lm">
<span class="s h g f nf ng"><span><a href="https://medium.com/m/signin?actionUrl=%2F_%2Fvote%2Fwalmartglobaltech%2Faf688aa1b1b8&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fwalmartglobaltech%2Fbuilding-domain-driven-microservices-af688aa1b1b8&amp;source=post_actions_footer-----af688aa1b1b8---------------------clap_footer-----------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">
<div class="az lq lr ls lt lu lv lw r lx ly">
<span class="s h g f nf ng"><svg width="33" height="33" viewbox="0 0 33 33" aria-label="clap">
<path d="M28.86 17.34l-3.64-6.4c-.3-.43-.71-.73-1.16-.8a1.12 1.12 0 0 0-.9.21c-.62.5-.73 1.18-.32 2.06l1.22 2.6 1.4 2.45c2.23 4.09 1.51 8-2.15 11.66a9.6 9.6 0 0 1-.8.71 6.53 6.53 0 0 0 4.3-2.1c3.82-3.82 3.57-7.87 2.05-10.39zm-6.25 11.08c3.35-3.35 4-6.78 1.98-10.47L21.2 12c-.3-.43-.71-.72-1.16-.8a1.12 1.12 0 0 0-.9.22c-.62.49-.74 1.18-.32 2.06l1.72 3.63a.5.5 0 0 1-.81.57l-8.91-8.9a1.33 1.33 0 0 0-1.89 1.88l5.3 5.3a.5.5 0 0 1-.71.7l-5.3-5.3-1.49-1.49c-.5-.5-1.38-.5-1.88 0a1.34 1.34 0 0 0 0 1.89l1.49 1.5 5.3 5.28a.5.5 0 0 1-.36.86.5.5 0 0 1-.36-.15l-5.29-5.29a1.34 1.34 0 0 0-1.88 0 1.34 1.34 0 0 0 0 1.89l2.23 2.23L9.3 21.4a.5.5 0 0 1-.36.85.5.5 0 0 1-.35-.14l-3.32-3.33a1.33 1.33 0 0 0-1.89 0 1.32 1.32 0 0 0-.39.95c0 .35.14.69.4.94l6.39 6.4c3.53 3.53 8.86 5.3 12.82 1.35zM12.73 9.26l5.68 5.68-.49-1.04c-.52-1.1-.43-2.13.22-2.89l-3.3-3.3a1.34 1.34 0 0 0-1.88 0 1.33 1.33 0 0 0-.4.94c0 .22.07.42.17.61zm14.79 19.18a7.46 7.46 0 0 1-6.41 2.31 7.92 7.92 0 0 1-3.67.9c-3.05 0-6.12-1.63-8.36-3.88l-6.4-6.4A2.31 2.31 0 0 1 2 19.72a2.33 2.33 0 0 1 1.92-2.3l-.87-.87a2.34 2.34 0 0 1 0-3.3 2.33 2.33 0 0 1 1.24-.64l-.14-.14a2.34 2.34 0 0 1 0-3.3 2.39 2.39 0 0 1 3.3 0l.14.14a2.33 2.33 0 0 1 3.95-1.24l.09.09c.09-.42.29-.83.62-1.16a2.34 2.34 0 0 1 3.3 0l3.38 3.39a2.17 2.17 0 0 1 1.27-.17c.54.08 1.03.35 1.45.76.1-.55.41-1.03.9-1.42a2.12 2.12 0 0 1 1.67-.4 2.8 2.8 0 0 1 1.85 1.25l3.65 6.43c1.7 2.83 2.03 7.37-2.2 11.6zM13.22.48l-1.92.89 2.37 2.83-.45-3.72zm8.48.88L19.78.5l-.44 3.7 2.36-2.84zM16.5 3.3L15.48 0h2.04L16.5 3.3z" fill-rule="evenodd"></path></svg></span>
</div></a></span></span>
</div>
<div class="s lz ma mb mc nh ni nj nk nl nm">
<div class="gq ne mg">
<p class="ce b eu cg ek">
<button class="ck cl au av aw ax ay az ba bb cm cn be co cp">641<span class="s h g f nf ng">&#160;claps</span></button>
</p>
</div>
</div>
</div>
</div>
<div class="s nn no np nq nr"></div>
<div class="mj n o lh">
<button class="lt lr az"><span class="ns s h g f nf ng"><svg width="33" height="33" viewbox="0 0 33 33" fill="none" class="r" aria-label="responses">
<path clip-rule="evenodd" d="M24.28 25.5l.32-.29c2.11-1.94 3.4-4.61 3.4-7.56C28 11.83 22.92 7 16.5 7S5 11.83 5 17.65s5.08 10.66 11.5 10.66c1.22 0 2.4-.18 3.5-.5l.5-.15.41.33a8.86 8.86 0 0 0 4.68 2.1 7.34 7.34 0 0 1-1.3-4.15v-.43zm1 .45c0 1.5.46 2.62 1.69 4.44.22.32.01.75-.38.75a9.69 9.69 0 0 1-6.31-2.37c-1.2.35-2.46.54-3.78.54C9.6 29.3 4 24.09 4 17.65 4 11.22 9.6 6 16.5 6S29 11.22 29 17.65c0 3.25-1.42 6.18-3.72 8.3z"></path></svg></span><span class="nt s nb nc nd e d"><svg width="25" height="25" class="r" aria-label="responses">
<path d="M19.07 21.12a6.33 6.33 0 0 1-3.53-1.1 7.8 7.8 0 0 1-.7-.52c-.77.21-1.57.32-2.38.32-4.67 0-8.46-3.5-8.46-7.8C4 7.7 7.79 4.2 12.46 4.2c4.66 0 8.46 3.5 8.46 7.8 0 2.06-.85 3.99-2.4 5.45a6.28 6.28 0 0 0 1.14 2.59c.15.21.17.48.06.7a.69.69 0 0 1-.62.38h-.03zm0-1v.5l.03-.5h-.03zm-3.92-1.64l.21.2a6.09 6.09 0 0 0 3.24 1.54 7.14 7.14 0 0 1-.83-1.84 5.15 5.15 0 0 1-.16-.75 2.4 2.4 0 0 1-.02-.29v-.23l.18-.15a6.6 6.6 0 0 0 2.3-4.96c0-3.82-3.4-6.93-7.6-6.93-4.19 0-7.6 3.11-7.6 6.93 0 3.83 3.41 6.94 7.6 6.94.83 0 1.64-.12 2.41-.35l.28-.08z" fill-rule="evenodd"></path></svg></span></button>
<div class="s gq nu ml nv mn nw mp nx ny nz oa">
<p class="ce b eu cg ek">
<button class="lt lr az">5<!-- --> <span class="s h g f nf ng">response<!-- -->s</span></button>
</p>
</div>
</div>
</div>
<div class="n o">
<div class="gd s ap">
<button class="ck cl au av aw ax ay az ba bb cm cn be co cp" aria-label="Share on twitter"><svg width="29" height="29" class="ge">
<path d="M22.05 7.54a4.47 4.47 0 0 0-3.3-1.46 4.53 4.53 0 0 0-4.53 4.53c0 .35.04.7.08 1.05A12.9 12.9 0 0 1 5 6.89a5.1 5.1 0 0 0-.65 2.26c.03 1.6.83 2.99 2.02 3.79a4.3 4.3 0 0 1-2.02-.57v.08a4.55 4.55 0 0 0 3.63 4.44c-.4.08-.8.13-1.21.16l-.81-.08a4.54 4.54 0 0 0 4.2 3.15 9.56 9.56 0 0 1-5.66 1.94l-1.05-.08c2 1.27 4.38 2.02 6.94 2.02 8.3 0 12.86-6.9 12.84-12.85.02-.24 0-.43 0-.65a8.68 8.68 0 0 0 2.26-2.34c-.82.38-1.7.62-2.6.72a4.37 4.37 0 0 0 1.95-2.51c-.84.53-1.81.9-2.83 1.13z"></path></svg></button>
</div>
<div class="gd s ap">
<button class="ck cl au av aw ax ay az ba bb cm cn be co cp" aria-label="Share on linkedin"><svg width="29" height="29" viewbox="0 0 29 29" fill="none" class="ge">
<path d="M5 6.36C5 5.61 5.63 5 6.4 5h16.2c.77 0 1.4.61 1.4 1.36v16.28c0 .75-.63 1.36-1.4 1.36H6.4c-.77 0-1.4-.6-1.4-1.36V6.36z"></path>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.76 20.9v-8.57H7.89v8.58h2.87zm-1.44-9.75c1 0 1.63-.65 1.63-1.48-.02-.84-.62-1.48-1.6-1.48-.99 0-1.63.64-1.63 1.48 0 .83.62 1.48 1.59 1.48h.01zM12.35 20.9h2.87v-4.79c0-.25.02-.5.1-.7.2-.5.67-1.04 1.46-1.04 1.04 0 1.46.8 1.46 1.95v4.59h2.87v-4.92c0-2.64-1.42-3.87-3.3-3.87-1.55 0-2.23.86-2.61 1.45h.02v-1.24h-2.87c.04.8 0 8.58 0 8.58z" fill="#fff"></path></svg></button>
</div>
<div class="gd s ap">
<button class="ck cl au av aw ax ay az ba bb cm cn be co cp" aria-label="Share on facebook"><svg width="29" height="29" class="ge">
<path d="M23.2 5H5.8a.8.8 0 0 0-.8.8V23.2c0 .44.35.8.8.8h9.3v-7.13h-2.38V13.9h2.38v-2.38c0-2.45 1.55-3.66 3.74-3.66 1.05 0 1.95.08 2.2.11v2.57h-1.5c-1.2 0-1.48.57-1.48 1.4v1.96h2.97l-.6 2.97h-2.37l.05 7.12h5.1a.8.8 0 0 0 .79-.8V5.8a.8.8 0 0 0-.8-.79"></path></svg></button>
</div>
<div class="ob s ap">
<div class="ge">
<span><a href="https://medium.com/m/signin?actionUrl=%2F_%2Fbookmark%2Fp%2Faf688aa1b1b8&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fwalmartglobaltech%2Fbuilding-domain-driven-microservices-af688aa1b1b8&amp;source=post_actions_footer--------------------------bookmark_footer-----------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener"><svg width="25" height="25" viewbox="0 0 25 25">
<path d="M19 6a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v14.66h.01c.01.1.05.2.12.28a.5.5 0 0 0 .7.03l5.67-4.12 5.66 4.13a.5.5 0 0 0 .71-.03.5.5 0 0 0 .12-.29H19V6zm-6.84 9.97L7 19.64V6a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v13.64l-5.16-3.67a.49.49 0 0 0-.68 0z" fill-rule="evenodd"></path></svg></a></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div class="n p">
<div class="ab ac ae af ag dk ai aj">
<div class="oc bh od mu s oe z">
<div class="s g">
<div class="of og s gq">
<div class="s t oj ok">
<span class="s oh am oi"><a rel="noopener" href="/@chandrarramalingam?source=follow_footer-------------------------------------"><img alt="Chandra Ramalingam" class="s eq bx ol" src="https://miro.medium.com/fit/c/160/160/1*nMWlywHdNTt8EoNNNPUzdw.jpeg" width="80" height="80" /></a></span>
</div>
<div class="om s on">
<p class="ce b cf oo op ch ci">
<span class="s oh am oi">Written by</span>
</p>
</div>
<div class="om oq n on">
<div class="aj n o em">
<h2 class="ce hm or os dm ek">
<span class="s oh am oi"><a class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener" href="/@chandrarramalingam?source=follow_footer-------------------------------------">Chandra Ramalingam</a></span>
</h2>
<div class="s g">
<span class="s oh am oi"><span><button class="ce b eu cg ff ot fh fi fj fk fl bb fm fn fo fp fq fr fs da ft fu">Follow</button></span></span>
</div>
</div>
</div>
<div class="om ou s on bi">
<div class="ov s">
<p class="ce b kz ow ch">
Distinguished Software Engineer @ WalmartLabs, based in San Francisco; California, working on building large scale grocery eCommerce platforms
</p>
</div>
<div class="ox oy bi">
<span><button class="ce b eu cg ff ot fh fi fj fk fl bb fm fn fo fp fq fr fs da ft fu">Follow</button></span>
</div>
</div>
</div>
<div class="oc s"></div>
<div class="of og s gq">
<div class="s t oj ok">
<span class="s oh am oi"><a href="/walmartglobaltech?source=follow_footer-------------------------------------" rel="noopener"><img alt="Walmart Global Tech Blog" class="fq ol bx" src="https://miro.medium.com/fit/c/160/160/1*quUoN1GMDA3fwyaPGdTYFQ.jpeg" width="80" height="80" /></a></span>
</div>
<div class="om oq n on">
<div class="aj n o em">
<h2 class="ce hm or os dm ek">
<span class="s oh am oi"><a href="/walmartglobaltech?source=follow_footer-------------------------------------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">Walmart Global Tech Blog</a></span>
</h2>
<div class="s g">
<div class="ft" aria-hidden="false" aria-describedby="collectionFollowPopover" aria-labelledby="collectionFollowPopover">
<div class="n lh">
<span class="s oh am oi"><button class="ce b eu cg ff ot fh fi fj fk fl bb fm fn fo fp fq fr fs da ft fu">Follow</button></span>
</div>
</div>
</div>
</div>
</div>
<div class="om oz s on bi">
<div class="ov s">
<p class="ce b kz ow ch">
Were powering the next great retail disruption. Learn more about ushttps://www.linkedin.com/company/walmartglobaltech/
</p>
</div>
<div class="ox oy bi">
<div class="ft" aria-hidden="false" aria-describedby="collectionFollowPopover" aria-labelledby="collectionFollowPopover">
<div class="n lh">
<span><button class="ce b eu cg ff ot fh fi fj fk fl bb fm fn fo fp fq fr fs da ft fu">Follow</button></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="ox bi">
<div class="pa s">
<div class="n lh">
<div class="pb s">
<a rel="noopener" href="/@chandrarramalingam?source=follow_footer-------------------------------------"><img alt="Chandra Ramalingam" class="s eq pc pd" src="https://miro.medium.com/fit/c/80/80/1*nMWlywHdNTt8EoNNNPUzdw.jpeg" width="40" height="40" /></a>
</div>
<div class="et s">
<p class="ce b pe pf pg ch ci">
Written by
</p>
<div class="n lh">
<h2 class="ce hm kz cg dm ek">
<a class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener" href="/@chandrarramalingam?source=follow_footer-------------------------------------">Chandra Ramalingam</a>
</h2>
<div class="et s">
<span><button class="ce b cf cg ff fg fh fi fj fk fl bb fm fn fo fp fq fr fs da ft fu">Follow</button></span>
</div>
</div>
<div class="ph s">
<p class="ce b eu cg ch">
Distinguished Software Engineer @ WalmartLabs, based in San Francisco; California, working on building large scale grocery eCommerce platforms
</p>
</div>
</div>
</div>
<div class="pa s">
<div class="n lh">
<a href="/walmartglobaltech?source=follow_footer-------------------------------------" rel="noopener"><img alt="Walmart Global Tech Blog" class="fq pd pc" src="https://miro.medium.com/fit/c/80/80/1*quUoN1GMDA3fwyaPGdTYFQ.jpeg" width="40" height="40" /></a>
<div class="et s">
<div class="n lh">
<h2 class="ce hm kz cg dm ek">
<a href="/walmartglobaltech?source=follow_footer-------------------------------------" class="ck cl au av aw ax ay az ba bb cm cn be co cp" rel="noopener">Walmart Global Tech Blog</a>
</h2>
<div class="et s">
<div class="ft" aria-hidden="false" aria-describedby="collectionFollowPopover" aria-labelledby="collectionFollowPopover">
<div class="n lh">
<span><button class="ce b cf cg ff fg fh fi fj fk fl bb fm fn fo fp fq fr fs da ft fu">Follow</button></span>
</div>
</div>
</div>
</div>
<div class="ph s">
<p class="ce b eu cg ch">
Were powering the next great retail disruption. Learn more about ushttps://www.linkedin.com/company/walmartglobaltech/
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="s pi z">
<div class="n p">
<div class="ab ac ae af ag ah ai aj">
<div class="pj pk s">
<div class="pl lb pm pk s pn po">
<h2 class="ce hm pp pq hq pr ps hu pt pu hy pv pw ic px py ig ek">
More From Medium
</h2>
</div>
<div class="bu n lh mt pz qa qb qc qd qe qf qg qh qi qj qk ql qm qn">
<div class="qo qp qq qr qs qt qu qv qw qx qy qz ra rb rc rd re rf rg rh ri">
<div class="rj rk s">
<div class="aj gv">
<div class="n em">
<div class="s bp rl rm rn">
<div class="ro s">
<h2 class="ce hm rp rq hq rr rs hu rt ru hy rv rw ic rx ry ig ek">
<a rel="noopener" href="/dev-genius/how-to-deploy-a-webpage-for-free-af3588cd32f9?source=post_internal_links---------0----------------------------">How to Deploy A Webpage for Free</a>
</h2>
</div>
<div class="o n">
<div class="aj s">
<div class="n">
<div style="flex:1">
<div class="cq n o ew">
<span class="ce b eu cg ek"><span class="ce b cf cg ek"><a href="https://fengyuan-yap.medium.com/?source=post_internal_links---------0----------------------------" class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener">Gen_Yap</a> <span><!-- -->in<!-- --> <a href="/dev-genius?source=post_internal_links---------0----------------------------" class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener">Dev Genius</a></span></span></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="et gf s rz sa">
<a class="ck cl au av aw ax ay az ba bb cm cn be co cp s" rel="noopener" href="/dev-genius/how-to-deploy-a-webpage-for-free-af3588cd32f9?source=post_internal_links---------0----------------------------">
<div class="gy s gq gz">
<div class="sb hb s">
<div class="tx ty t u v gv aj bk gw gx"></div><img class="gt gu sc sd se sf sg sh si sj sk sl c" width="70" height="70" role="presentation" /><noscript><img class="sc sd se sf sg sh si sj sk sl" src="https://miro.medium.com/fit/c/140/140/1*AyvI1QQtdGybyk4tEKkcfA.png" width="70" height="70" srcset="https://miro.medium.com/fit/c/96/140/1*AyvI1QQtdGybyk4tEKkcfA.png 48w, https://miro.medium.com/fit/c/140/140/1*AyvI1QQtdGybyk4tEKkcfA.png 70w" sizes="70px" role="presentation" /></noscript>
</div>
</div></a>
</div>
</div>
</div>
</div>
</div>
<div class="qo qp qq qr qs qt qu qv qw qx qy qz ra rb rc rd re rf rg rh ri">
<div class="rj rk s">
<div class="aj gv">
<div class="n em">
<div class="s bp rl rm rn">
<div class="ro s">
<h2 class="ce hm rp rq hq rr rs hu rt ru hy rv rw ic rx ry ig ek">
<a rel="noopener" href="/thron-tech/what-we-learned-by-working-with-mongodbs-collection-index-ae3fe77cd90a?source=post_internal_links---------1----------------------------">What We Learned by Working with MongoDBs Collection Index</a>
</h2>
</div>
<div class="o n">
<div class="aj s">
<div class="n">
<div style="flex:1">
<div class="cq n o ew">
<span class="ce b eu cg ek"><span class="ce b cf cg ek"><a class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener" href="/@edoardo.zanon?source=post_internal_links---------1----------------------------">Edoardo Zanon</a> <span><!-- -->in<!-- --> <a href="/thron-tech?source=post_internal_links---------1----------------------------" class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener">THRON tech blog</a></span></span></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="et gf s rz sa">
<a class="ck cl au av aw ax ay az ba bb cm cn be co cp s" rel="noopener" href="/thron-tech/what-we-learned-by-working-with-mongodbs-collection-index-ae3fe77cd90a?source=post_internal_links---------1----------------------------">
<div class="gy s gq gz">
<div class="sb hb s">
<div class="tx ty t u v gv aj bk gw gx"></div><img class="gt gu sc sd se sf sg sh si sj sk sl c" width="70" height="70" role="presentation" /><noscript><img class="sc sd se sf sg sh si sj sk sl" src="https://miro.medium.com/fit/c/140/140/1*UCy5FoeaXqL1jch1P8yAVg.png" width="70" height="70" srcset="https://miro.medium.com/fit/c/96/140/1*UCy5FoeaXqL1jch1P8yAVg.png 48w, https://miro.medium.com/fit/c/140/140/1*UCy5FoeaXqL1jch1P8yAVg.png 70w" sizes="70px" role="presentation" /></noscript>
</div>
</div></a>
</div>
</div>
</div>
</div>
</div>
<div class="qo qp qq qr qs qt qu qv qw qx qy qz ra rb rc rd re rf rg rh ri">
<div class="rj rk s">
<div class="aj gv">
<div class="n em">
<div class="s bp rl rm rn">
<div class="ro s">
<h2 class="ce hm rp rq hq rr rs hu rt ru hy rv rw ic rx ry ig ek">
<a rel="noopener" href="/firebase-developers/how-to-write-a-c-backend-for-a-unity-game-using-firebase-and-googles-cloud-run-adebf79a57f?source=post_internal_links---------2----------------------------">How to write a C# backend for a Unity game using Firebase and Googles Cloud Run</a>
</h2>
</div>
<div class="o n">
<div class="aj s">
<div class="n">
<div style="flex:1">
<div class="cq n o ew">
<span class="ce b eu cg ek"><span class="ce b cf cg ek"><a class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener" href="/@pux0r3?source=post_internal_links---------2----------------------------">Patrick Martin</a> <span><!-- -->in<!-- --> <a href="/firebase-developers?source=post_internal_links---------2----------------------------" class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener">Firebase Developers</a></span></span></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="et gf s rz sa">
<a class="ck cl au av aw ax ay az ba bb cm cn be co cp s" rel="noopener" href="/firebase-developers/how-to-write-a-c-backend-for-a-unity-game-using-firebase-and-googles-cloud-run-adebf79a57f?source=post_internal_links---------2----------------------------">
<div class="gy s gq gz">
<div class="sb hb s">
<div class="tx ty t u v gv aj bk gw gx"></div><img class="gt gu sc sd se sf sg sh si sj sk sl c" width="70" height="70" role="presentation" /><noscript><img class="sc sd se sf sg sh si sj sk sl" src="https://miro.medium.com/fit/c/140/140/1*C8q8echAmfXhCaaGCRBgQg.png" width="70" height="70" srcset="https://miro.medium.com/fit/c/96/140/1*C8q8echAmfXhCaaGCRBgQg.png 48w, https://miro.medium.com/fit/c/140/140/1*C8q8echAmfXhCaaGCRBgQg.png 70w" sizes="70px" role="presentation" /></noscript>
</div>
</div></a>
</div>
</div>
</div>
</div>
</div>
<div class="qo qp qq qr qs qt qu qv qw qx qy qz ra rb rc rd re rf rg rh ri">
<div class="rj rk s">
<div class="aj gv">
<div class="n em">
<div class="s bp rl rm rn">
<div class="ro s">
<h2 class="ce hm rp rq hq rr rs hu rt ru hy rv rw ic rx ry ig ek">
<a rel="noopener" href="/@seandlg/what-nand2tetris-has-taught-me-about-computers-and-more-importantly-about-learning-aebc84af3030?source=post_internal_links---------3----------------------------">What Nand2Tetris Has Taught Me About Computers, and, More Importantly, About Learning</a>
</h2>
</div>
<div class="o n">
<div class="aj s">
<div class="n">
<div style="flex:1">
<div class="cq n o ew">
<span class="ce b eu cg ek"><span class="ce b cf cg ek"><a class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener" href="/@seandlg?source=post_internal_links---------3----------------------------">Sean Eulenberg</a></span></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="et gf s rz sa">
<a class="ck cl au av aw ax ay az ba bb cm cn be co cp s" rel="noopener" href="/@seandlg/what-nand2tetris-has-taught-me-about-computers-and-more-importantly-about-learning-aebc84af3030?source=post_internal_links---------3----------------------------">
<div class="gy s gq gz">
<div class="sb hb s">
<div class="tx ty t u v gv aj bk gw gx"></div><img class="gt gu sc sd se sf sg sh si sj sk sl c" width="70" height="70" role="presentation" /><noscript><img class="sc sd se sf sg sh si sj sk sl" src="https://miro.medium.com/fit/c/140/140/1*uM00gLLMizLgqZSGFXx91Q.gif" width="70" height="70" srcset="https://miro.medium.com/fit/c/96/140/1*uM00gLLMizLgqZSGFXx91Q.gif 48w, https://miro.medium.com/fit/c/140/140/1*uM00gLLMizLgqZSGFXx91Q.gif 70w" sizes="70px" role="presentation" /></noscript>
</div>
</div></a>
</div>
</div>
</div>
</div>
</div>
<div class="qo qp qq qr qs qt qu qv qw qx qy qz ra rb rc rd re rf rg rh ri">
<div class="rj rk s">
<div class="aj gv">
<div class="n em">
<div class="s bp rl rm rn">
<div class="ro s">
<h2 class="ce hm rp rq hq rr rs hu rt ru hy rv rw ic rx ry ig ek">
<a rel="noopener" href="/qimi-techblog/connecting-mongodb-hosted-in-mongo-atlas-with-powerbi-including-m0-clusters-ae02fbef0c7d?source=post_internal_links---------4----------------------------">Connecting MongoDB hosted in Mongo Atlas with PowerBI (including M0 clusters)</a>
</h2>
</div>
<div class="o n">
<div class="aj s">
<div class="n">
<div style="flex:1">
<div class="cq n o ew">
<span class="ce b eu cg ek"><span class="ce b cf cg ek"><a class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener" href="/@luismego?source=post_internal_links---------4----------------------------">Luis Mego</a> <span><!-- -->in<!-- --> <a href="/qimi-techblog?source=post_internal_links---------4----------------------------" class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener">Qimi TechBlog</a></span></span></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="et gf s rz sa">
<a class="ck cl au av aw ax ay az ba bb cm cn be co cp s" rel="noopener" href="/qimi-techblog/connecting-mongodb-hosted-in-mongo-atlas-with-powerbi-including-m0-clusters-ae02fbef0c7d?source=post_internal_links---------4----------------------------">
<div class="gy s gq gz">
<div class="sb hb s">
<div class="tx ty t u v gv aj bk gw gx"></div><img class="gt gu sc sd se sf sg sh si sj sk sl c" width="70" height="70" role="presentation" /><noscript><img class="sc sd se sf sg sh si sj sk sl" src="https://miro.medium.com/fit/c/140/140/1*k4AG-v6LVc2r7KjlWJT0nQ.png" width="70" height="70" srcset="https://miro.medium.com/fit/c/96/140/1*k4AG-v6LVc2r7KjlWJT0nQ.png 48w, https://miro.medium.com/fit/c/140/140/1*k4AG-v6LVc2r7KjlWJT0nQ.png 70w" sizes="70px" role="presentation" /></noscript>
</div>
</div></a>
</div>
</div>
</div>
</div>
</div>
<div class="qo qp qq qr qs qt qu qv qw qx qy qz ra rb rc rd re rf rg rh ri">
<div class="rj rk s">
<div class="aj gv">
<div class="n em">
<div class="s bp rl rm rn">
<div class="ro s">
<h2 class="ce hm rp rq hq rr rs hu rt ru hy rv rw ic rx ry ig ek">
<a href="https://lucasjellema.medium.com/install-sqlcl-on-oracle-cloud-infrastructure-cloud-shell-and-make-it-work-against-an-autonomous-adfe9d195f6f?source=post_internal_links---------5----------------------------" rel="noopener">Install SQLcl on Oracle Cloud Infrastructure Cloud Shell and make it work against an Autonomous…</a>
</h2>
</div>
<div class="o n">
<div class="aj s">
<div class="n">
<div style="flex:1">
<div class="cq n o ew">
<span class="ce b eu cg ek"><span class="ce b cf cg ek"><a href="https://lucasjellema.medium.com/?source=post_internal_links---------5----------------------------" class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener">Lucas Jellema</a></span></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="et gf s rz sa">
<a href="https://lucasjellema.medium.com/install-sqlcl-on-oracle-cloud-infrastructure-cloud-shell-and-make-it-work-against-an-autonomous-adfe9d195f6f?source=post_internal_links---------5----------------------------" class="ck cl au av aw ax ay az ba bb cm cn be co cp s" rel="noopener">
<div class="gy s gq gz">
<div class="sb hb s">
<div class="tx ty t u v gv aj bk gw gx"></div><img class="gt gu sc sd se sf sg sh si sj sk sl c" width="70" height="70" role="presentation" /><noscript><img class="sc sd se sf sg sh si sj sk sl" src="https://miro.medium.com/fit/c/140/140/0*-LuouuC_WZIcFrjT.png" width="70" height="70" srcset="https://miro.medium.com/fit/c/96/140/0*-LuouuC_WZIcFrjT.png 48w, https://miro.medium.com/fit/c/140/140/0*-LuouuC_WZIcFrjT.png 70w" sizes="70px" role="presentation" /></noscript>
</div>
</div></a>
</div>
</div>
</div>
</div>
</div>
<div class="qo qp qq qr qs qt qu qv qw qx qy qz ra rb rc rd re rf rg rh ri">
<div class="rj rk s">
<div class="aj gv">
<div class="n em">
<div class="s bp rl rm rn">
<div class="ro s">
<h2 class="ce hm rp rq hq rr rs hu rt ru hy rv rw ic rx ry ig ek">
<a rel="noopener" href="/zero-equals-false/iaas-vs-paas-infrastructure-as-a-service-vs-platform-as-a-service-ade4fd55b027?source=post_internal_links---------6----------------------------">IaaS vs PaaS: Infrastructure as a Service VS Platform as a Service</a>
</h2>
</div>
<div class="o n">
<div class="aj s">
<div class="n">
<div style="flex:1">
<div class="cq n o ew">
<span class="ce b eu cg ek"><span class="ce b cf cg ek"><a class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener" href="/@salmansaleem920?source=post_internal_links---------6----------------------------">Salman Saleem</a> <span><!-- -->in<!-- --> <a href="/zero-equals-false?source=post_internal_links---------6----------------------------" class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener">Zero Equals False</a></span></span></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="et gf s rz sa">
<a class="ck cl au av aw ax ay az ba bb cm cn be co cp s" rel="noopener" href="/zero-equals-false/iaas-vs-paas-infrastructure-as-a-service-vs-platform-as-a-service-ade4fd55b027?source=post_internal_links---------6----------------------------">
<div class="gy s gq gz">
<div class="sb hb s">
<div class="tx ty t u v gv aj bk gw gx"></div><img class="gt gu sc sd se sf sg sh si sj sk sl c" width="70" height="70" role="presentation" /><noscript><img class="sc sd se sf sg sh si sj sk sl" src="https://miro.medium.com/fit/c/140/140/0*2-e4yteKZrmvdHNj.jpg" width="70" height="70" srcset="https://miro.medium.com/fit/c/96/140/0*2-e4yteKZrmvdHNj.jpg 48w, https://miro.medium.com/fit/c/140/140/0*2-e4yteKZrmvdHNj.jpg 70w" sizes="70px" role="presentation" /></noscript>
</div>
</div></a>
</div>
</div>
</div>
</div>
</div>
<div class="qo qp qq qr qs qt qu qv qw qx qy qz ra rb rc rd re rf rg rh ri">
<div class="rj rk s">
<div class="aj gv">
<div class="n em">
<div class="s bp rl rm rn">
<div class="ro s">
<h2 class="ce hm rp rq hq rr rs hu rt ru hy rv rw ic rx ry ig ek">
<a rel="noopener" href="/@kalex.bica/building-real-time-apps-aef53dbb443b?source=post_internal_links---------7----------------------------">Building Real-time Apps</a>
</h2>
</div>
<div class="o n">
<div class="aj s">
<div class="n">
<div style="flex:1">
<div class="cq n o ew">
<span class="ce b eu cg ek"><span class="ce b cf cg ek"><a class="ck cl au av aw ax ay az ba bb fd be co cp" rel="noopener" href="/@kalex.bica?source=post_internal_links---------7----------------------------">Kalex Bica</a></span></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="et gf s rz sa">
<a class="ck cl au av aw ax ay az ba bb cm cn be co cp s" rel="noopener" href="/@kalex.bica/building-real-time-apps-aef53dbb443b?source=post_internal_links---------7----------------------------">
<div class="gy s gq gz">
<div class="sb hb s">
<div class="tx ty t u v gv aj bk gw gx"></div><img class="gt gu sc sd se sf sg sh si sj sk sl c" width="70" height="70" role="presentation" /><noscript><img class="sc sd se sf sg sh si sj sk sl" src="https://miro.medium.com/fit/c/140/140/1*EHvQbmuYMHf0gJkM3IWB8g.png" width="70" height="70" srcset="https://miro.medium.com/fit/c/96/140/1*EHvQbmuYMHf0gJkM3IWB8g.png 48w, https://miro.medium.com/fit/c/140/140/1*EHvQbmuYMHf0gJkM3IWB8g.png 70w" sizes="70px" role="presentation" /></noscript>
</div>
</div></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sm s sn so">
<div class="n p">
<div class="ab ac ae af ag ah ai aj">
<div class="sp sq of n em g">
<div class="sr n em">
<div class="ss s st">
<div class="ro s">
<a href="https://medium.com/about?autoplay=1&amp;source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb su sv be sw sx" rel="noopener">
<h2 class="ce hm sy ow dm sz">
Learn more.
</h2></a>
</div>
<p class="ce b eu cg ta">
Medium<!-- --> is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface.<!-- --> <a href="https://medium.com/about?autoplay=1&amp;source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb be sw sx hj" rel="noopener">Learn more</a>
</p>
</div>
<div class="ss s st">
<div class="ro s">
<a href="https://medium.com/topics?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb su sv be sw sx" rel="noopener">
<h2 class="ce hm sy ow dm sz">
Make <!-- -->Medium<!-- --> yours.
</h2></a>
</div>
<p class="ce b eu cg ta">
Follow the writers, publications, and topics that matter to you, and youll see them on your homepage and in your inbox.<!-- --> <a href="https://medium.com/topics?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb be sw sx hj" rel="noopener">Explore</a>
</p>
</div>
<div class="ss s st">
<div class="ro s">
<a href="https://about.medium.com/creators/?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb su sv be sw sx" rel="noopener">
<h2 class="ce hm sy ow dm sz">
Share your thinking.
</h2></a>
</div>
<p class="ce b eu cg ta">
If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. Its easy and free to post your thinking on any topic.<!-- --> <a href="https://about.medium.com/creators/?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb be sw sx hj" rel="noopener">Write on <!-- -->Medium</a>
</p>
</div>
</div>
</div>
<div class="n ky">
<div class="n o em">
<a class="ck cl au av aw ax ay az ba bb su sv be sw sx" rel="noopener" href="/?source=post_page-----af688aa1b1b8--------------------------------"><svg viewbox="0 0 3940 610" class="fh tb">
<path d="M594.79 308.2c0 163.76-131.85 296.52-294.5 296.52S5.8 472 5.8 308.2 137.65 11.69 300.29 11.69s294.5 132.75 294.5 296.51M917.86 308.2c0 154.16-65.93 279.12-147.25 279.12s-147.25-125-147.25-279.12S689.29 29.08 770.61 29.08s147.25 125 147.25 279.12M1050 308.2c0 138.12-23.19 250.08-51.79 250.08s-51.79-112-51.79-250.08 23.19-250.08 51.8-250.08S1050 170.09 1050 308.2M1862.77 37.4l.82-.18v-6.35h-167.48l-155.51 365.5-155.51-365.5h-180.48v6.35l.81.18c30.57 6.9 46.09 17.19 46.09 54.3v434.45c0 37.11-15.58 47.4-46.15 54.3l-.81.18V587H1327v-6.35l-.81-.18c-30.57-6.9-46.09-17.19-46.09-54.3V116.9L1479.87 587h11.33l205.59-483.21V536.9c-2.62 29.31-18 38.36-45.68 44.61l-.82.19v6.3h213.3v-6.3l-.82-.19c-27.71-6.25-43.46-15.3-46.08-44.61l-.14-445.2h.14c0-37.11 15.52-47.4 46.08-54.3m97.43 287.8c3.49-78.06 31.52-134.4 78.56-135.37 14.51.24 26.68 5 36.14 14.16 20.1 19.51 29.55 60.28 28.09 121.21zm-2.11 22h250v-1.05c-.71-59.69-18-106.12-51.34-138-28.82-27.55-71.49-42.71-116.31-42.71h-1c-23.26 0-51.79 5.64-72.09 15.86-23.11 10.7-43.49 26.7-60.45 47.7-27.3 33.83-43.84 79.55-47.86 130.93-.13 1.54-.24 3.08-.35 4.62s-.18 2.92-.25 4.39a332.64 332.64 0 0 0-.36 21.69C1860.79 507 1923.65 600 2035.3 600c98 0 155.07-71.64 169.3-167.8l-7.19-2.53c-25 51.68-69.9 83-121 79.18-69.76-5.22-123.2-75.95-118.35-161.63m532.69 157.68c-8.2 19.45-25.31 30.15-48.24 30.15s-43.89-15.74-58.78-44.34c-16-30.7-24.42-74.1-24.42-125.51 0-107 33.28-176.21 84.79-176.21 21.57 0 38.55 10.7 46.65 29.37zm165.84 76.28c-30.57-7.23-46.09-18-46.09-57V5.28L2424.77 60v6.7l1.14-.09c25.62-2.07 43 1.47 53.09 10.79 7.9 7.3 11.75 18.5 11.75 34.26v71.14c-18.31-11.69-40.09-17.38-66.52-17.38-53.6 0-102.59 22.57-137.92 63.56-36.83 42.72-56.3 101.1-56.3 168.81C2230 518.72 2289.53 600 2378.13 600c51.83 0 93.53-28.4 112.62-76.3V588h166.65v-6.66zm159.29-505.33c0-37.76-28.47-66.24-66.24-66.24-37.59 0-67 29.1-67 66.24s29.44 66.24 67 66.24c37.77 0 66.24-28.48 66.24-66.24m43.84 505.33c-30.57-7.23-46.09-18-46.09-57h-.13V166.65l-166.66 47.85v6.5l1 .09c36.06 3.21 45.93 15.63 45.93 57.77V588h166.8v-6.66zm427.05 0c-30.57-7.23-46.09-18-46.09-57V166.65L3082 212.92v6.52l.94.1c29.48 3.1 38 16.23 38 58.56v226c-9.83 19.45-28.27 31-50.61 31.78-36.23 0-56.18-24.47-56.18-68.9V166.66l-166.66 47.85V221l1 .09c36.06 3.2 45.94 15.62 45.94 57.77v191.27a214.48 214.48 0 0 0 3.47 39.82l3 13.05c14.11 50.56 51.08 77 109 77 49.06 0 92.06-30.37 111-77.89v66h166.66v-6.66zM3934.2 588v-6.67l-.81-.19c-33.17-7.65-46.09-22.07-46.09-51.43v-243.2c0-75.83-42.59-121.09-113.93-121.09-52 0-95.85 30.05-112.73 76.86-13.41-49.6-52-76.86-109.06-76.86-50.12 0-89.4 26.45-106.25 71.13v-69.87l-166.66 45.89v6.54l1 .09c35.63 3.16 45.93 15.94 45.93 57V588h155.5v-6.66l-.82-.2c-26.46-6.22-35-17.56-35-46.66V255.72c7-16.35 21.11-35.72 49-35.72 34.64 0 52.2 24 52.2 71.28V588h155.54v-6.66l-.82-.2c-26.46-6.22-35-17.56-35-46.66v-248a160.45 160.45 0 0 0-2.2-27.68c7.42-17.77 22.34-38.8 51.37-38.8 35.13 0 52.2 23.31 52.2 71.28V588z"></path></svg></a>
<p class="ce b eu cg ta"></p>
<div class="ph tc n em td am">
<p class="ce b kz ow sz">
<a href="https://medium.com/about?autoplay=1&amp;source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb fd be sw sx" rel="noopener">About</a>
</p>
<p class="ce b kz ow sz">
<a href="https://help.medium.com/hc/en-us?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb fd be sw sx" rel="noopener">Help</a>
</p>
<p class="ce b kz ow sz">
<a href="https://policy.medium.com/medium-terms-of-service-9db0094a1e0f?source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb fd be sw sx" rel="noopener">Legal</a>
</p>
</div>
</div>
<div class="ox te tf am">
<p class="ce b kz ow ta">
Get the Medium app
</p>
</div>
<div class="ox te tg am th">
<div class="ti s">
<a href="https://itunes.apple.com/app/medium-everyones-stories/id828256236?pt=698524&amp;mt=8&amp;ct=post_page&amp;source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb su sv be sw sx" rel="noopener nofollow"><img alt="A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store" class="" src="https://miro.medium.com/max/270/1*Crl55Tm6yDNMoucPo1tvDg.png" width="135" height="41" /></a>
</div>
<div class="s">
<a href="https://play.google.com/store/apps/details?id=com.medium.reader&amp;source=post_page-----af688aa1b1b8--------------------------------" class="ck cl au av aw ax ay az ba bb su sv be sw sx" rel="noopener nofollow"><img alt="A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store" class="" src="https://miro.medium.com/max/270/1*W_RAPQ62h0em559zluJLdQ.png" width="135" height="41" /></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
<![CDATA[
window.__BUILD_ID__ = "main-20210218-082621-43a3bdd9e6"
]]>
</script>
<script>
<![CDATA[
window.__GRAPHQL_URI__ = "https://medium.com/_/graphql"
]]>
</script>
<script>
<![CDATA[
window.__PRELOADED_STATE__ = {"auroraPage":{"isAuroraPageEnabled":false},"bookReader":{"reader":{"currentAsset":null,"settingsPanelIsOpen":false,"settings":{"fontFamily":"SANS_SERIF_1","fontScale":"M","publisherStyling":true,"textAlignement":"START","theme":"White"}}},"cache":{"experimentGroupSet":false,"group":"disabled","tags":[],"serverVariantState":""},"client":{"isBot":false,"isEu":false,"isUs":false,"isNativeMedium":false,"isSafariMobile":false,"isSafari":false,"inAppBrowserName":"","routingEntity":{"type":"DEFAULT","explicit":false},"supportsWebp":true},"config":{"nodeEnv":"production","version":"main-20210218-082621-43a3bdd9e6","isTaggedVersion":false,"target":"production","productName":"Medium","publicUrl":"https:\u002F\u002Fcdn-client.medium.com\u002Flite","authDomain":"medium.com","authGoogleClientId":"216296035834-k1k6qe060s2tp2a2jam4ljdcms00sttg.apps.googleusercontent.com","favicon":"production","glyphUrl":"https:\u002F\u002Fglyph.medium.com","branchKey":"key_live_ofxXr2qTrrU9NqURK8ZwEhknBxiI6KBm","lightStep":{"name":"lite-web","host":"lightstep.medium.systems","token":"ce5be895bef60919541332990ac9fef2","appVersion":"main-20210218-082621-43a3bdd9e6"},"algolia":{"appId":"MQ57UUUQZ2","apiKeySearch":"394474ced050e3911ae2249ecc774921","indexPrefix":"medium_","host":"-dsn.algolia.net"},"recaptchaKey":"6Lfc37IUAAAAAKGGtC6rLS13R1Hrw_BqADfS1LRk","recaptcha3Key":"6Lf8R9wUAAAAABMI_85Wb8melS7Zj6ziuf99Yot5","datadog":{"clientToken":"pub853ea8d17ad6821d9f8f11861d23dfed","context":{"deployment":{"target":"production","tag":"main-20210218-082621-43a3bdd9e6","commit":"43a3bdd9e681c5e8b0c6eb1145d85a838032d5ff"}},"datacenter":"us"},"isAmp":false,"googleAnalyticsCode":"UA-24232453-2","signInWallCustomDomainCollectionIds":["3a8144eabfe3","336d898217ee","61061eb0c96b","138adf9c44c","819cc2aaeee0"],"mediumOwnedAndOperatedCollectionIds":["544c7006046e","bcc38c8f6edf","444d13b52878","8d6b8a439e32","92d2092dc598","1285ba81cada","cb8577c9149e","8ccfed20cbb2","ae2a65f35510","3f6ecf56618","7b6769f2748b","fc8964313712","ef8e90590e66","191186aaafa0","d944778ce714","bdc4052bbdba","88d9857e584e","9dc80918cc93","8a9336e5bb4","cef6983b292","54c98c43354d","193b68bd4fba","b7e45b22fec3","55760f21cdc5"],"tierOneDomains":["medium.com","thebolditalic.com","arcdigital.media","towardsdatascience.com","uxdesign.cc","codeburst.io","psiloveyou.xyz","writingcooperative.com","entrepreneurshandbook.co","prototypr.io","betterhumans.coach.me","theascent.pub"],"topicsToFollow":["d61cf867d93f","8a146bc21b28","1eca0103fff3","4d562ee63426","aef1078a3ef5","e15e46793f8d","6158eb913466","55f1c20aba7a","3d18b94f6858","4861fee224fd","63c6f1f93ee","1d98b3a9a871","decb52b64abf","ae5d4995e225","830cded25262"],"defaultImages":{"avatar":{"imageId":"1*dmbNkD5D-u45r44go_cf0g.png","height":150,"width":150},"orgLogo":{"imageId":"1*OMF3fSqH8t4xBJ9-6oZDZw.png","height":106,"width":545},"postLogo":{"imageId":"1*kFrc4tBFM_tCis-2Ic87WA.png","height":810,"width":1440},"postPreviewImage":{"imageId":"1*hn4v1tCaJy7cWMyb0bpNpQ.png","height":386,"width":579}},"performanceTags":[],"collectionStructuredData":{"8d6b8a439e32":{"name":"Elemental","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F980\u002F1*9ygdqoKprhwuTVKUM0DLPA@2x.png","width":980,"height":159}}},"3f6ecf56618":{"name":"Forge","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F596\u002F1*uULpIlImcO5TDuBZ6lm7Lg@2x.png","width":596,"height":183}}},"ae2a65f35510":{"name":"GEN","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F264\u002F1*RdVZMdvfV3YiZTw6mX7yWA.png","width":264,"heigh
]]>
</script>
<script>
<![CDATA[
window.__APOLLO_STATE__ = {"ROOT_QUERY":{"__typename":"Query","viewer":null,"variantFlags":[{"__typename":"VariantFlag","name":"allow_access","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"allow_signup","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"allow_test_auth","valueType":{"__typename":"VariantFlagString","value":"disallow"}},{"__typename":"VariantFlag","name":"android_enable_lock_responses","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"assign_default_topic_to_posts","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"available_annual_plan","valueType":{"__typename":"VariantFlagString","value":"2c754bcc2995"}},{"__typename":"VariantFlag","name":"available_monthly_plan","valueType":{"__typename":"VariantFlagString","value":"60e220181034"}},{"__typename":"VariantFlag","name":"bane_add_user","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"bane_verify_domain","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"branch_seo_metadata","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"browsable_stream_config_bucket","valueType":{"__typename":"VariantFlagString","value":"curated-topics"}},{"__typename":"VariantFlag","name":"coronavirus_topic_recirc","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"covid_19_cdc_banner","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"default_seo_post_titles","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"digest_delivery_window_one_hour_after","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"disable_android_subscription_activity_carousel","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"disable_ios_resume_reading_toast","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"disable_ios_subscription_activity_carousel","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"disable_mobile_featured_chunk","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"disable_post_recommended_from_friends_provider","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_android_local_currency","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_annual_renewal_reminder_email","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_app_flirty_thirty","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_apple_parse_expires_at","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_apple_sign_in","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_apple_webhook","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_apple_webhook_renewal_failure","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_aurora_about_page_routing","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_aurora_general_admission","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_aurora_nav","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_aurora_profile_page","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_
]]>
</script>
<script src="https://cdn-client.medium.com/lite/static/js/manifest.ffa371ee.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/8247.8b14dd5f.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/main.858e8c70.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/5573.159bf40f.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/instrumentation.42411c75.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/reporting.18206c56.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/1752.a348f767.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/4464.c01c0ad8.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/8342.6aa0b45e.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/1148.fddd1e85.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/9692.c7888f17.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/9274.31b70f4f.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/5064.8cb1757e.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/7993.0060594e.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/2846.53a861ed.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/7012.ff2007f2.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/9972.695972af.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/5127.810d9eac.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/7117.1eb92b8c.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/8751.4957eb83.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/9458.a2aa1247.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/7131.899bb049.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/8127.a11eec65.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/463.14fe51be.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/1373.c07e51db.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/587.409e5550.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/2514.c67fd96a.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/3874.b445ae8d.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/857.01632080.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/8286.08280ee0.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/5429.b9d510a9.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/8831.4a0b4fad.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/2450.bfc2d9e5.chunk.js"></script>
<script src="https://cdn-client.medium.com/lite/static/js/Post.b2e9c91e.chunk.js"></script>
<script>
<![CDATA[
window.main();
]]>
</script>
<script src="//d1z2jf7jlzjs58.cloudfront.net/keys/medium.com/p.js" async="async" id="parsely-cf"></script>
<script src="https://accounts.google.com/gsi/client" async="async"></script><iframe src="https://a16180790160.cdn.optimizely.com/client_storage/a16180790160.html" hidden="" tabindex="-1" title="Optimizely Internal Frame" height="0" width="0" style="display: none;"></iframe>
</body>
</html>