Services by Lifecycle

alex_brajkovic1 pts0 comments

Services By Lifecycle - michaelnygard.com<br>Services By Lifecycle<br>Posted on 05 Jan 2018<br>in<br>architecture,<br>microservices,<br>business-process<br>This post took a lot longer to pull together than I expected. Not<br>because it was hard to write, but because it was too easy to write<br>too much. Like a<br>pre-bonsai tree, it<br>would grow out of control and get pruned back over and over.<br>In the meantime, I delivered<br>a workshop<br>and spent some lovely holiday time with my family.<br>But it&rsquo;s a new year now, and January is devoid of holidays so it&rsquo;s<br>high time I got back to business.<br>Avoiding the Entity Service<br>In my<br>last post,<br>I made a case against entity services. To recap, an entity service is<br>a set of CRUD operations on a business entity such as Person,<br>Location, Contract, Order, etc. It&rsquo;s an antipattern because it<br>creates high semantic and operational coupling. Edge services suffer<br>from common-mode failures through their shared dependency on the<br>entity services. Changes or outages in the entity services have large<br>&ldquo;failure domains.&rdquo;<br>A lot of good advice springs from Eric Evan&rsquo;s hugely influential book<br>&ldquo;Domain-Driven Design.&rdquo; It was written before the service era, but<br>seems to apply well now. I&rsquo;m not an expert on DDD, though, so I&rsquo;m<br>going to offer some techniques that may or may not be described<br>there. (I dig the &ldquo;bounded context&rdquo; idea, but need to re-read the<br>whole book before I comment on it more.)<br>There are several ways to avoid entity services. This post explores<br>just one (though it&rsquo;s one I particularly like.) Future posts will look<br>at additional techniques.<br>Focus on Behavior Instead of Data<br>When you think about what a service knows, you always end up back at<br>CRUD. I recommend thinking in terms of the service&rsquo;s<br>responsibilities. (And don&rsquo;t say it&rsquo;s responsible for knowing some<br>data!) Does it apply policy? Does it aggregate a stream of concepts<br>into a summary? Does it facilitate some kinds of changes? Does it<br>calculate something? And so on.<br>Once you know what a service does, you can figure out what it needs to<br>know. For instance, a service that restricts content delivery based on<br>local laws needs to know a few things:<br>What jurisdiction applies?<br>What classifiers are on the content?<br>What classifiers are not allowed in that jurisdiction?<br>Notice that #1 and #2 are specific to an individual request, while #3<br>is slowly-changing data. Thus it makes sense for the service to know<br>#3 and be told #1 and #2.<br>This leads us to a deeper discussion about what the service knows. How<br>does that data get into the service? Is there a GUI for a legal team?<br>Maybe there&rsquo;s a feed we can purchase from a data vendor. Maybe we need<br>to apply machine learning based on lawsuits and penalties incurred<br>when we violate local laws. (I&rsquo;m kidding! Don&rsquo;t do the last one!) The<br>answers to these questions will firm up your design and situate your<br>service in its ecosystem.<br>Model Like It&rsquo;s 1999<br>When modeling, I like to use a technique from object-oriented<br>design. CRC cards let me lay out<br>physical tokens that represent services. Then I can play a game where<br>I simulate a request coming in at the edge. A service can add<br>information to a request and pass it along to another service,<br>following the &ldquo;Tell, Don&rsquo;t Ask&rdquo; principle.<br>If you are in a team, you can deal out cards to players then simulate<br>a request by passing a physical object around. That will quickly<br>reveal gaps in a design. Some common gaps that I see:<br>A service doesn&rsquo;t know where to send the request. It lacks<br>knowledge of other services that can continue processing. The<br>solution is either to statically introduce it to the next party or<br>to provide URLs in the data that lead to the handler.<br>A service receives a request that is insufficient. The incoming<br>request either lacks information or has an implicit context that<br>should be turned into data on the request.<br>While playing the CRC game, it&rsquo;s OK to assume your service already has<br>data it naturally depends on. That is, slowly-changing data the<br>service uses should be considered an asynchronous process relative to<br>the current request. But do make note of that slowly-changing data so<br>you remember to build in the flows needed to populate it.<br>If you follow &ldquo;Tell, Don&rsquo;t Ask&rdquo; strictly, then the activation set will<br>be a strict tree. Anywhere a service calls out to more than one<br>downstream, it should be sending instructions forward in parallel<br>rather than serially making queries followed by an instruction.<br>Dealing with Consistency<br>If it were just a matter of passing requests along with extra data, then life would be simple. As often happens, trouble comes from side effects.<br>Services are not pure functions. If a service call always results in the same result for the same parameters, then you don&rsquo;t need a service. Make a library and avoid the operational overhead! Services only make sense when they change...

service rsquo services data request entity

Related Articles