mca bloghttp://www.amundsen.com/blog/making progressSat, 27 Apr 2024 04:01:00 GMTen-us180been a long time...http://www.amundsen.com/blog/archives/1171http://www.amundsen.com/blog/archives/1171Fri, 11 Nov 2022 14:42:00 GMT<p>been quite a while since i blogged here.</p> <p>let's see if this gets picked up by feediverse and posted to my mastodon instance account.</p> <p>who knows. this might get to be a habit again...</p> API Strategy at Mulesoft in 2019http://www.amundsen.com/blog/archives/1170http://www.amundsen.com/blog/archives/1170Mon, 03 Jun 2019 15:52:00 GMT<p> <a href="http://mamund.site44.com/images/2019-06-03-strategy.jpeg"> <img src="http://mamund.site44.com/images/2019-06-03-strategy.jpeg" width="300" class="inline" align="right"/> </a> i'm happy to announce that, starting in June of this year, I'll be working as an <b>API Strategy Advisor</b> with <a href="https://www.mulesoft.com/">Mulesoft</a>. this gives me a chance to team up w/ my long-time friend and colleague, <a href="https://twitter.com/MattMcLartyBC" title="@MattMcLartyBC">Matt McLarty</a> and to renew acquaintances w/ a handful of really talented and experienced API professionals at Mulesoft. </p> <h2>API Strategy</h2> <p> Matt and I (along with <a href="https://twitter.com/inadarei" title="@inadarei">Irakli</a> and <a href="https://twitter.com/mitraman" title="@mitraman">Ronnie</a>) worked together on the <a href="http://g.mamund.com/msabook">Microservices Architecture</a> book and it will be good to be working with him again. that book, and a more recent one -- <a href="http://g.mamund.com/cambook" title="CAMBook">Continuous API Management</a> (with <a href="https://twitter.com/medjawii" title="@medjawii">Mehdi</a> and <a href="https://twitter.com/dret" title="@dret">Erik</a>) -- focus on the steps <i>beyond</i> API as a "thing" and reflect a trend i see growing in the API community. that trend is to view APIs as a <i>strategy</i> for accomplishing <i>business objectives</i>. </p> <p> as few as five years ago just <i>having</i> an API program could set you apart from your competition in the market. however, that is no longer the case. now, it is important the APIs that you spend you time and money to build, test, deploy, and support actually provide a measurable business advantage. that's where an <b>API Strategy</b> comes into play. </p> <p> and companies that can enable that API Stratgey -- companies that not only understand it but can also help others adopt it -- are the companies i am anxious to work with, share, and learn from. and that is why today i am honored and excited to be able to begin working with Mulesoft and promote this "next level" approach to APIs. </p> <h2>MuleSoft Connect</h2> <p> over the coming weeks and months, Matt and I will be working to collect and share API Strategy experiences from companies of all sizes from around the world. we'll be taking the time to meet with and talk to industry leaders as well as promising startups in order to learn how they are using APIs to go to the "next level" and we'll be working to conslidate and share their knowledge and experience at events across the globe. </p> <p> along these lines, Mulesoft will be hosting a series of events -- <a href="https://connect.mulesoft.com/">Mulesoft CONNECT</a> -- at cities in North America, Europe, and Asia. Matt and I will be at the next <a href="https://connect.mulesoft.com/events/connect/san-francisco-bay-area">CONNECT event in San Francisco</a> later this month. you can also check the ongoing schedule to see when we'll be at a city near you. i'm looking forward to these opportunities to share and learn about the role API Strategy is playing in the community and hope to see you there. </p> <h2>2019 and Beyond</h2> <p> of course, strategy is just one step in the process of identifying, implementing, evaluating, and improving your organization's business and the IT ecosystem that supports it. and this is not an overnight process. it takes time, persistence, dedication, and patience. i'm excited to be able to join Mulesoft in helping promote this approach and looking forward to seeing how it can advance to role of APIs in businesses worldwide not just this year but also for many years to come. </p>Preserving the Egg on the Webhttp://www.amundsen.com/blog/archives/1168http://www.amundsen.com/blog/archives/1168Sat, 31 Mar 2018 12:32:00 GMT<p> <a href="http://www.eoht.info/m/page/Entropy+%28unscrambled+eggs%29"><img src="http://image.wikifoundry.com/image/1/pmNLAbSRbTp9LGK0xIIUng74900/GW523H188" width="300" class="inline" align="right" /></a> When I plan out an implementation for the Web, one of the things I think about is the problem of "breaking eggs." One great example of this is the old adage, "You can't make an omelette without breaking some eggs." That's cute. It reminds us that there are times in our lives when we need to commit. When we need to forge ahead, even if some people might disagree, even if there seems to be "no turning back." </p> <p>However, this "omelette" adage is not what I mean when I think about Web implementations and eggs.</p> <p> Instead, I think about <a href="http://www.eoht.info/m/page/Entropy+%28unscrambled+eggs%29">entropy</a> and how you cannot 'unscramble' an egg. I won't go into the physics or philosophical nuances of this POV except to say, when I am working on a web implementation I work very hard to avoid 'breaking any eggs' since it will be quite unlikely that I'll ever be able to put those eggs back together again.</p> <p>I don't want my Web solution to end up like <a href="https://en.m.wikipedia.org/wiki/Humpty_Dumpty">Humtpy Dumpty!</a></p> <h3>Web Interactions as Eggs</h3> <p> The web is a virtual world. It is a highly-distributed and non-deterministic -- much like our physical world. We can't know all the influences and their effects on us. We can only know our immediate surroundings and surmise the influences based on what we observe locally. The world is a random place. </p> <p>So each time we fill out a form and press "send", each time we click on a link, we're taking a risk and stepping into the unknown. For example:</p> <ul> <li>Is there really a page at the other end of this link or is there a dreaded 404 waiting for me at the other end?</li> <li>Have I filled out the form correctly or will I get a 400 error instead?</li> <li>Or, have I filled out the form correctly, only to encouter a 500-level server error?</li> <li>Finally, what if I've filled out the form, pressed "send" and never get a response back at all? what do I do now?</li> </ul> <h3>But What Can Be Done?</h3> <p>When I set out to implement a solution on the Web, I want to make sure to take these types of outcomes into account. I say "take them into account" because the truth is that I cannot <i>prevent</i> them. Most of the time these kinds of failures are outside my control. However, using the notion of <a href="http://resilienthealthcare.net/onewebmedia/WhitePaperFinal.pdf">Safety-I and Safety-II</a> from Erik Hollnagel, I can adopt a different strategy: While can't prevent system failures, I can work to survive them.</p> <p>So how can I survive unanticipated and un-preventable errors in system? I can do this by making sure each interaction is not an "egg-breaking" event. An "egg-breaker" is an action that cannot be un-done, cannot be reversed. In the web world, this is an interaction that has only two outcomes: "success or a mess."</p> <p>A great example of the sad end of the "success-or-a-mess" moment is an action like "Delete All Data." We've probably all experienced a moment like this. Most likely we've answered "yes" or "OK" to a confirmation dialog and the moment we did, we realized (too late) that we "<a href="https://media1.tenor.com/images/4988bf571adbd4edc5df437a8530eba4/tenor.gif?itemid=5056977">chose poorly</a>." There was no easy way to fix our mistake. We had a mess on our hands.</p> <p>The obvious answer to this kind of mess is to support an "undo" action to reverse the "do." This turns an "egg-breaking" event into and "egg-preserving" event. And that's what I try to do with as much of my Web implementations as possible -- preserve the egg.</p> <p>Let's look at some other ways to prevent breaking eggs when implementing solutions in a non-deterministic world...</p> <h3>Network-Level Idempotency</h3> <p> One of the ways you can avoid "a mess" is to make sure your actions are idempotent at the network level. That means they are <b>repeatable</b> and you get the same results every time. Think of an SQL UPDATE statement. You can update the the <code>firstName</code> field with the value <code>"Mike"</code> over and over and the <code>firstName</code> field will always have the same value: <code>"Mike"</code>.</p> <p>In the HTTP world, both the <code>PUT</code> and <code>DELETE</code> methods are designed as idempotent actions. This means, in cases where you commit a <code>PUT</code> and never recieve a response, you can repeat that action without worry of "breaking the egg."</p> <p>Relying on network-level idempotency is very important when you are creating autonomous services that interact with each other without direct human intervention. Robots have a hard time dealing with non-idempotent failures.</p> <h3>Service-Level Event Sourcing</h3> <p> At the individual service level, a good way to "preserve the egg" is to make all writes (actions that change that state of things) <b>reversible</b>. Martin Fowler shows how this can be done using <a href="https://martinfowler.com/eaaDev/EventSourcing.html">Event Sourcing</a>. Event Sourcing was explained to me by Capital One's, <a href="https://twitter.com/inadarei">Irakli Nadareishvili</a> as a kind of "debit-and-credit" approach to data updates. You arrange writes as actions that can be reversed by another write. Essentially, you're not "un-doing" something, you're "re-doing" it. </p> <p>Fowler shows that, by implementing state changes using Event-Sourcing, you get several benefits including:</p> <ul> <li>detailed change logs</li> <li>the ability to run a complete rebuild</li> <li>the ability to run a "temporal query" (based on a set date/time)</li> <li>the power to replay past transctions (to fix or analyze system state)</li> </ul> <p>I like say that, with Event-Sourcing, you can't reverse the arrow of time, but you can move the <i>cursor</i>.</p> <h3>Solution-Level Sagas</h3> <p> In 1987, Garcia-Molina and Salem published a paper simply titled "<a href="https://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf">Sagas</a>." This paper describes how to handle long-lived transactions in a large-scale system where the typical Two-Phase Commit pattern results in a high degree of latency. Sagas are a another great way to keep from "breaking the egg."</p> <p> <a href="https://twitter.com/crichardson">Chris Richardson</a> has done some excellent work on <a href="http://microservices.io/patterns/data/saga.html">how to implement Sagas</a>. I like to think of Sagas as a way to bring the service-level event-sourcing pattern to a solution-level of multiple interoperable services. Richardson points out there is more than one way to implement Sagas for distributed systems including: </p> <ul> <li>Choreography-based (each service publishes their own saga events)</li> <li>Orchestration-based (each saga is managed by a central saga orchestrator)</li> </ul> <p>Sagas are a great way to "preserve the egg" when working with multiple services to solve a single problem.</p> <h3>And so...</h3> <p> When putting together your Web implementations, it is important to think about "preserving the egg" -- making sure that you can reverse any action in case of an unexpected system failure. Working to avoid "breaking the egg" adds a valuable level of resilience to your implementations. This can protect your services, your data, and your users from possibly catastrophic events that lead to "a mess" that is difficult and costly to fix.</p> <p>In this post, I shared three possible ways to do this at the network, service, and solution level. There are probably more. The most important thing to remember is that the Web is a highly-distributed, non-deterministic world. You can't <i>prevent</i> bad things from happening, but with enough planning and attention to details, you can <i>survive</i> them.</p> <h4>now that this post is done, anyone hungry for an omelette?</h4>Model Actions, Not Datahttp://www.amundsen.com/blog/archives/1167http://www.amundsen.com/blog/archives/1167Tue, 13 Feb 2018 22:40:00 GMT<blockquote> I've not blogged in quite a while here -- lots of reasons, none of them sufficient. So, today, i break the drought with a simple rant. Enjoy -- <b>mca</b> </blockquote> <p> <a href="https://images-na.ssl-images-amazon.com/images/M/MV5BMjA3MjMzMTk0MF5BMl5BanBnXkFtZTcwMjI5NjMyNA@@._V1_.jpg"> <img src="https://images-na.ssl-images-amazon.com/images/M/MV5BMjA3MjMzMTk0MF5BMl5BanBnXkFtZTcwMjI5NjMyNA@@._V1_.jpg" width="150" align="right" class="inline"/> </a> It is really encouraging to see so many examples of companies and even industries spending valuable resources (time, money, people) on efforts to define, implement, and advocate for "open" APIs. in the last few years i've seen a steady rise in the number of requests to me for guidance on how to go about this work of creating and supporting APIs, too. And i hear similar stories from other API evangelists and practitioners up and down the spectrum from startups to multi-nationals. And, like i said, it is encouraging to see. </p> <p> But… </p> <p> Even though i've been quite explicit in my general guidance through lots of media and modes (interviews, presentations, even full-length books), it is frustrating to see many people continue to make the same simple mistakes when going about the work of designing and deploying their APIs. so much so, that i've decided to "dis-hibernate" this blog in order to squawk about it openly. </p> <p> And chief among these frustrations is the repeated attempts to design APIs based on data models. Your database is not your API! Stop it. Just stop. </p> <p> Unless you are offering API consumers a SaaS (storage-as-a-service) you SHOULD NOT be using your data model as any guide for your API design. Not. At. All. </p> <blockquote> <p> Arthur Jensen (In a loud, angry voice): "You are messing with the primal forces of nature Mr. Beale. And YOU! WILL! ATTONE!" </p> <p> (Arthur pauses and leans in to whisper in Beale's ear) </p> <p> Arthur: "Am I getting through to you, Mr. Beale?" </p> <p align="right"> <a href="https://www.imdb.com/title/tt0074958/quotes?item=qt0447849">Network (1976)</a> </p> </blockquote> <p> When you cast about for a handle on how to go about designing your API, the answer is straightforward and simple: Model your Actions. </p> <p> It can't be stated any more directly. Model your Actions. </p> <p> Don't get caught up in your current data model. Don't fall down the rabbit hole of your existing internal object model. Just. don't. </p> <p> Need more? Here's a handy checklist: </p> <ol> <li> Start with a list of actions to be completed. (<a href="https://www.christenseninstitute.org/jobs-to-be-done/">Jobs To Be Done</a>) -- if that sparks your brain. </li> <li> Determine all the data elements that must be passed when performing that action. </li> <li> Identify all the data elements to be returned when the action is performed. Be sure to account for partial or total failure of the attempted action. </li> <li> Rinse and repeat. </li> </ol> <blockquote> <a href="https://twitter.com/leonardr" title="@leonardr">Leonard Richardson</a> and I offer up a long-form description of this four-step plan in our book <a href="http://restfulwebapis.com/">"RESTful Web APIs"</a>. </blockquote> <p> Once you feel good about your list of actions and data points (input and output), collect related actions together. Each collection identifies a context. A boundary for a component. That might sound <a href="https://en.wikipedia.org/wiki/Domain-driven_design" title="Domain-Driven Design">familiar</a> to some folks. </p> <p> Now you have an API to implement and deploy. When implementing this API, you can sort out any object models or data models you want to use (pre-existing or not). But that's all hum-drum implementation detail. Internal stuff no one consuming the API should know or care about. </p> <p> All they care about are the possible actions to perform. And the data points to be supplied and returned. </p> <p> That's it. Simple. </p> <p> Of course, simple is not <i>easy</i>. </p> <blockquote> <p> "I would have written a shorter letter but I just didn't have the time." </p> <p align="right">-- various attributions.</p> </blockquote> <p> now, if a simple rant is not enough, i offer up an epigram i first shared publicly back in 2016: </p> <blockquote> <p> remember, when designing your #WebAPI, your data model is not your object model is not your resource model is not your message model #API360 </p> <p align="right"><a href="https://twitter.com/mamund/status/767212233759657984" title="@mamund">@mamund</a></p> </blockquote> <p> And if a single epigram is not motivation enough, how about <a href="http://amundsen.com/talks/2016-11-apistrat-wadm/index.html" title="WADM">a whole slide deck</a> from APIStrat 2016 devoted to explaining that simple phrase? </p> <p> Now, armed (again) with this clear, simple advice, you're ready to avoid the debacle of data-centric industry-wide APIs. </p> <p> <b>just go out there and take action (not data)!</b> </p>an online tutorial -- with friendshttp://www.amundsen.com/blog/archives/1166http://www.amundsen.com/blog/archives/1166Tue, 02 Feb 2016 21:22:00 GMT<p> <a href="http://www.oreilly.com/online-training/hypermedia-node-html5.html"> <img src="http://mamund.site44.com/images/2016-01-06-training-01.png" height="175" align="right" class="inline" /> </a> there just a few days left before my live O'Reilly <a href="http://www.oreilly.com/online-training/hypermedia-node-html5.html">Implementing Hypermedia</a> online tutorial on february 9th (11AM to 5PM EST). and i'm spending the day tweaking the slides and working up the six hands-on lessons. as i do this, i'm really looking forward to the interactive six hour session. we'll be covering quite a bit in a single day, too. </p> <h4>the agenda</h4> <p>most of the material comes from my 2011 O'Reilly book <a href="http://shop.oreilly.com/product/0636920020530.do">Building Hypermedia APIs with HTML5 and Node</a>. however, i've added a few things from <a href="http://shop.oreilly.com/product/0636920028468.do">RESTFul Web APIs</a> by <a href="http://twitter.com/leonardr">Leonard Richardson</a> and even brought in a few items from my upcoming book <a href="http://shop.oreilly.com/product/0636920037958.do">RESTful Web Clients</a>. </p> <p>the high-level topics are:</p> <ul> <li>Designing a Hypermedia API</li> <li>Using the DORR Pattern for Coding Web APIs</li> <li>Understanding the Collection+JSON Media Type</li> <li>Building Hypermedia SPA Clients</li> </ul> <p> by the time the day is done, everyone will have a fully-functional Hypermedia API service up and running <b>and</b> a Cj-compliant general-pourpose hypermedia client that works w/ <i>ANY</i> Web API that supports the Collection+JSON media type. </p> <h4>Greenville Hypermedia Day</h4> <p> the tutorial is geared toward both individual and team participation. i know some companies are arranging a full-day session with their own dev teams for this, too. and i just heard about a cool event in Greenville, SC for people who want to get the "team" spirit... </p> <p> i found out that <a href="http://twitter.com/bigbluehat" title="@bigbluehat">Benjamin Young</a> is hosting a <a href="https://www.eventbrite.com/e/hypermedia-day-tickets-21235622318">Hypermedia Day</a> down in Greenville, SC on feb 9th. If you're in the area, you can sign up, show up, join the tutorial in progress, and chat it up w/ colleagues. I know Benjamin from our work together for <a href="http://restfest.org">RESTFest</a> and he's a good egg w/ lots of skills. He'll be doing a Q&amp;A during the breaks in the tutorial modules and i <i>think</i> he might have something planned as an "after-party" thing at the end of the day. </p> <p> if you're anywhere <i>near</i> Greenville, SC on feb-09, you should join Benjamin's <a href="https://www.eventbrite.com/e/hypermedia-day-tickets-21235622318">Hypermedia Day</a> festivities! </p> <h4>cut me some slack</h4> <p> i know most of the attendees are going "solo" -- just you, me, and the code -- that's cool. O'Reilly is hosting a live private Slack channel for everyone who signs up for the tutorial. I'll be around all day (and probably some time after that, too) so we can explore the exercises, work out any bugs, and just generally chat. </p> <h4>it's all ready!</h4> <p> so, as i wrap up the slides, the hands-on lessons, the github repo, and the heroku-hosted examples, i encourage you to <a href="http://www.oreilly.com/online-training/hypermedia-node-html5.html">sign up</a> and join us for a full day of hypermedia, NodeJS, and HTML5. </p> <h4>see you there!</h4>Dallas is my first stop in 2016http://www.amundsen.com/blog/archives/1165http://www.amundsen.com/blog/archives/1165Thu, 07 Jan 2016 17:56:00 GMT<p> <a title="By Herman Brosius (active 1870s). [Public domain], via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File%3AOld_map-Dallas-1872.jpg"><img width="150" class="inline" align="right" alt="Old map-Dallas-1872" src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Old_map-Dallas-1872.jpg/256px-Old_map-Dallas-1872.jpg"/></a> the week of january 11th i'll be in Dallas for two events. this is my first trip of 2016 and i'm looking forward to catching up w/ my Dallas peeps. I'll be visiting with the great folks at <a href="http://www.meetup.com/DFW-API-Professionals/events/227829495/" title="meetup page">DFW API Professionals</a> on Jan-13 and addressing a gathering of Dallas-area IT dignitaries at <a href="https://en.wikipedia.org/wiki/AT%26T_Stadium">AT&amp;T Stadium</a> during the day on the 14th. </p> <h4>DFW API Professionals</h4> <p> i've known <a href="https://twitter.com/traxo" title="@traxo">Traxo</a>'s <a href="https://twitter.com/stevenscg" title="@stevenscg">Chris Stevens</a> for several years and, when i learned i would be in Dallas in January, we were able to arrange an oppty for me to address his meetup group: <a href="http://www.meetup.com/DFW-API-Professionals/events/227829495/" title="meetup page">DFW API Professionals</a>. I'll be talking about and demoing hypermedia API client coding patterns and taking questions, too. check out the event and, if you can, join me and the whole <a href="https://twitter.com/DFW_API_Pros" title="@DFW_API_Pros">DFW API Pro</a> membership. </p> <h4>API Management Best Practices Discussion</h4> <p> on thursday, i'll be at the AT&amp;T Stadium with my fellow <a href="http://www.ca.com">CA</a> colleagues and folks from <a href="http://www.perficient.com/">Perficient</a> to join in the discussion on API mgmt and a look into the near future. i get to share the podium w/ CA SVp and Distinguished Engineer, <a href="https://twitter.com/kscottmorrison" title="@kscottmorrison">Scott Morrison</a>. in a lively open discussion (no slideware), we'll be covering API design, deployment, DevOps, Microservices, and IoT with Perficient's Director of Emerging Platform Solutions, <a href="https://twitter.com/anneladzem" title="@anneladzem">Annel Adzem</a>. stellar conversation, stunning view of the field -- what's not to like? </p> <h4>just the beginning</h4> <p> of course, this is just the start of my travels for 2016. i've already got the cities of Vancouver, Washington DC, E. Brunswick, Seoul, Tokyo, Melbourne, Sydney, San Francisco, Sao Paulo, Rio, Buenos Aries, and New York on my agenda. and that's just the first few months of 2016! </p> <p> gonna be another great year with the API Academy! if you're anywhere near those cities, keep in touch and i hope we meetup sometime soon. </p> Microservice Stylehttp://www.amundsen.com/blog/archives/1164http://www.amundsen.com/blog/archives/1164Wed, 25 Nov 2015 00:08:00 GMT<blockquote> With apologies to <a href="http://cobweb.cs.uga.edu/~eileen/1730/Readings/UNIX_Foreword.pdf">McIlroy, Pinson, and Tague</a>. </blockquote> <p> <a href="http://hightechhistory.com/tag/dennis-m-ritchie/"> <img src="http://hightechhistory.files.wordpress.com/2011/10/ritchie-thompson.jpg" width="150" align="right" class="inline" /> </a> </p> <p> A number of maxims have gained currency among the builders and users of microservices to explain and promote their characteristic style: </p> <p> <b>(i)</b> Make each microservice do one thing well. To do a new job, build afresh rather than complicate old microservices by adding new features. </p> <p> <b>(ii)</b> Expect the output of every microservice to become the input to another, as yet unknown, microservice. Don't clutter output with extraneous information. Avoid strongly-typed or binary input formats. Don't insist on object trees as input. </p> <p> <b>(iii)</b> Design and build microservices to be created and deployed early, ideally within weeks. Don't hesitate to throw away the clumsy parts and rebuild them. </p> <p> <b>(iv)</b> Use testing and deployment tooling (in preference to manual efforts) to lighten a programming task, even if you have to detour to build the tools and expect to throw some of them out after you've finished using them. </p>three keys to design-time governance: protocol, format, and vocabularyhttp://www.amundsen.com/blog/archives/1163http://www.amundsen.com/blog/archives/1163Sat, 07 Nov 2015 17:11:00 GMT<p> <a href="http://mamund.site44.com/images/2015-11-07-keys.jpg" title="Three Keys"> <img src="http://mamund.site44.com/images/2015-11-07-keys.jpg" width="150" align="right" class="inline" /> </a> this is my ring of keys -- just three of them: work, home, car. i've been focusing over the last couple years on <i>reducing</i>. cutting back. lightening my load, etc. and the keys are one of my more obvious examples of success. </p> <p> i've also been trying to lighten my load <i>cognitively</i> -- to reduce the amount of things i carry in my head and pare things down to essentials. i think it helps me focus on the things that matter when i carry less things around in my head. that's me. </p> <p> staring at my keys today lead me to something that's been on my mind lately. something i am seeing quite often when i visit customers. the approach these companies use for governing their IT development lack the clarity and focus of my "three keys." in fact, most of the time as i am reading these companies' governance documents, they make me <i>wince</i>. why? because they're bloated, over-bearing, and -- almost all of them -- making things worse, not better. </p> <h4>over-constraining makes everyone non-compliant</h4> <p> i am frequently asked to provide advice on design and implementation of API-related development programs -- most often APIs that run over HTTP. and, in that process, i am usually handed some from of "<a href="http://my.safaribooksonline.com/book/software-engineering-and-development/soa/9780132478373/soa-governance-technology/ch14lev1sec1">Design-Time Governance</a>" (DTG) document that has been written in-house. sometimes it is just a rough draft. sometims it is a detailed document running over 100 pages. but, while the details vary, there are general themes i see all too often. </p> <dl> <dt>Constraining HTTP</dt> <dd> almost every DTG approach i see lists things like HTTP methods (and how to use them), HTTP response codes (and what they mean), and HTTP Headers (including which new REQUIRED headers were invented for this organization). all carefully written. <b>and all terribly wrong</b>. putting limits on the use of standard protocols within your organization means every existing framework, library, and tool is essentially <i>non-compliant</i> for your shop. that's crazy. stop that! if your shop uses HTTP to get things done, just say so. don't try to re-invent, "improve", or otherwise muddle with the standard -- just use it. </dd> <dt>Designing URLs</dt> <dd> another thing i see in DTG documents is a section outlining the much-belabored and elaborate URLs design rules for the organization. Yikes! this is almost always an unnecessary level of "<a href="https://en.wikipedia.org/wiki/Parkinson%27s_law_of_triviality">bike-shedding</a>" that can only hold you back. designing URLs for your org (esp. large orgs) is a <a href="https://en.wikipedia.org/wiki/Snipe_hunt">fool's errand</a> -- you'll never get it right and you'll never be done with it. just stop. there are more than enough <a href="https://tools.ietf.org/html/rfc3986">agreed standards</a> on what makes up a valid URL and that's all you need to worry about. you should <a href="https://tools.ietf.org/html/rfc7320">resist the urge</a> to tell people how many slashes or dashes or dots MUST appear in a URL. it doesn't improve anything. <blockquote> look, i know that some orgs want to use URL design as a way to manage routing rules -- that's understandable. but, again, resist the urge to tell everyone in your org which URLs they can use for now and all eternity. some teams may not rely on the same route tooling and will use different methods. some may not use routing tools at all. and, if you change tooling after five years, your whole URL design scheme may become worthless. stop using URLs as your primary routing source. </blockquote> </dd> <dt>Canonical Models</dt> <dd> i really get depressed when i see all the work people put into negotiating and defining "<a href="https://en.wikipedia.org/wiki/Canonical_model">canonical models</a>" for the organization. like URL designs, <a href="https://www.innoq.com/en/blog/thoughts-on-a-canonical-data-model/">this always goes badly</a> sooner or later. stop trying to get everyone/every-team to use the same models! instead, use the same message formats. i know this is hard for people to grasp (i've seen your faces, srsly) but i can't emphasize this enough. there are several message formats <i>specifically designed</i> for data transfer between parties. use them! the only shared agreement that you need is the message format (along with the data elements carried <i>in</i> the message). </dd> <dt>Versioning Schemes</dt> <dd> here's one that just never seems to go away -- rules and processes for creating "new versions" of APIs. these things are a waste of time. <b>the phrase "new version" is a euphemism for "breaking changes" and this should never happen</b>. when you build sub-systems that are used by other teams/customers you are making a promise to them that you won't break things or invalidate their work (at least you SHOULD be making that promise!). it is not rocket-science to make backward-compatible changes -- just do it. once you finally accept your responsibility for not breaking anyone using your API, you can stop trying to come up w/ schemes to tell people you broke your promise to them and just get on with the work of building great software that works for a long time. </dd> </dl> <p> so, stop constraining HTTP, stop designing URLs, stop trying to dictate shared models, and forget about creating an endless series of breaking changes. "What then," you might ask, "IS the proper focus of design-time governance?" "How can I actually <i>govern</i> IT systems unless I control all these things?" </p> <h4>three keys form the base of design-time governance</h4> <p> ok, let me introduce you to my "three keys of DTG". these are not the ONLY things that need the focus on IT governance, but they are the <i>bare minimum</i> -- the essential building blocks. the starting point from which all other DTG springs. </p> <dl> <dt>Protocol Governance</dt> <dd> <p> first, all IT shops MUST provide protocol-level governance. you need to provide clear guidance and control over which application-level protocols are to be used when interacting with other parts of the org, other sub-systems, etc. and it is as simple as saying which protocols are REQUIRED, RECOMMENDED, and OPTIONAL. for example... </p> <p> "Here are BigCo, Inc. all installed components that provide an API MUST support <a href="https://tools.ietf.org/html/rfc7230">HTTP</a>. These components SHOULD also support <a href="https://tools.ietf.org/html/rfc6120">XMPP</a> and MAY also support <a href="https://tools.ietf.org/html/rfc7252">CoAP</a>. Any components that fail to pass this audit will be deemed non-compliant and will not be promoted to production." </p> <blockquote> you'll notice the CAPITALIZED words here. these are all special words taken from the IETF's <a href="https://tools.ietf.org/html/rfc2119">RFC2119</a>. they carry particular meaning here and your DTGs SHOULD use them. </blockquote> </dd> <dt>Format Governance</dt> <dd> <p> another <i>essential</i> governance element is the message formats used when passing data between sub-systems. again, nothing short of clear guidance will do here. and there is no reason to invent your own message-passing formats when there are so many good ones available. for example... </p> <p> "All API data responses passed between sub-systems MUST support <a href="http://www.w3.org/TR/2014/REC-html5-20141028/">HTML</a>. They SHOULD also support one of the following: <a href="http://amundsen.com/media-types/collection/">Collection+JSON</a>, <a href="http://stateless.co/hal_specification.html">HAL</a>, <a href="https://github.com/kevinswiber/siren">Siren</a>, or <a href="http://uberhypermedia.com">UBER</a>. sub-systems MAY also support responses in <a href="https://tools.ietf.org/html/rfc4287">Atom</a>, <a href="https://tools.ietf.org/html/rfc4180">CSV</a>, or <a href="http://yaml.org/spec/history/2001-05-26.html">YAML</a> where appropriate. When accepting data bodies on requests, all components MUST support <a href="https://tools.ietf.org/html/rfc1866#section-8.2.1">FORM-URLENCODED</a> and SHOULD support request bodies appropriate for related response formats (e.g. Collection+JSON, Siren, etc.). Any components that fail to pass this audit will be deemed non-compliant and will not be promoted to production." </p> <blockquote> you'll notice that my sample statement does not include TXT, JSON or XML as compliant API formats. why? because all of them suffer the same problem -- they are insufficiently structured formats. </blockquote> </dd> <dt>Vocabulary Governance</dt> <dd> <p> the first two keys are easy. have a meeting, argue with each other about which existing standards are acceptable and report the reusults. done. but, this last key (<a href="http://ceur-ws.org/Vol-866/keynote3.pdf">Vocabulary Governance</a>) is the hard one -- the kind of work for which enterprise-level governance exists. the one that will likely result in lots of angry meetings and may hurt some feelings. </p> <p> there MUST be an org-level committee that governs all the data names and action names for IT data transfers. this means there needs to be a shared dictionary (or set of them) that are the <i>final arbiter</i> of what a data field is <i>named</i> when it passes from one sub-system to the other. <a href="https://en.wikipedia.org/wiki/Domain-driven_design">managing the company domain vocabulary</a> is <b>the most important job of enterprise-level governance</b>. </p> <blockquote> the careful reader will see that i am not talking about governing <i>storage models</i> or <i>object models</i> here -- just the names of data fields passed within messages between sub-systems. understanding this is most <i>critical</i> to the success of your IT operations. models are the responsibility of local sub-systems. passing data <i>between</i> those sub-systems is the responsibility IT governance. </blockquote> </dd> </dl> <h4>what about all those "ilities"?</h4> <p> as i mentioned at the opening, these three keys form the <i>base</i> of a solid DTG. there are still many other <a href="https://en.wikipedia.org/wiki/Non-functional_requirement">desirable properties</a> of a safe and healthy IT program including availability, reliability, security, and many more. this is not about an "either/or" decision ("Well, I guess we have to choose between Mike's three keys and everything else, right?" -- ROFL!). we can discuss the many possible/desirable properties of your IT systems at some point in the near future -- <i>after</i> you implement your baseline. </p> <p> so, there you have it. protocol, format, vocabulary. get those three right and you will be laying the important foundation for an IT shop that can retain stability without rigidity; that can adapt over time by adding new protocols, formats, and vocabularies without breaking existing sub-systems or ending up in a deep hole of <a href="https://en.wikipedia.org/wiki/Technical_debt">technical-debt</a>. </p> <h4>those are the keys to a successful design-time governance plan.</h4>dftw - decoupled for the winhttp://www.amundsen.com/blog/archives/1162http://www.amundsen.com/blog/archives/1162Sun, 11 Oct 2015 23:51:00 GMT<p> <a title="By Daniel Schwen (Own work) [CC BY-SA 4.0 (http://creativecommons.org/licenses/by-sa/4.0)], via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File%3ATrain_coupling.jpg"> <img width="150" alt="Train coupling" src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/Train_coupling.jpg/307px-Train_coupling.jpg" align="right" class="inline"/> </a> it doesn't matter if your service is <a href="http://martinfowler.com/articles/microservices.html">"micro"</a> or <a href="http://martinfowler.com/bliki/ServiceOrientedAmbiguity.html">"oriented"</a>, if it's <a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">tightly coupled</a> -- especially if your service is on the Web -- you're going to be stuck nursing your service (and all it's consumers) through <a href="https://en.wikipedia.org/wiki/Software_versioning">lots of pain</a> every time each little change happens (<a href="https://en.wikipedia.org/wiki/Uniform_Resource_Locator">addresses</a>, <a href="https://en.wikipedia.org/wiki/Functional_specification">operations</a>, <a href="https://en.wikipedia.org/wiki/Parameter_(computer_programming)">arguments</a>, <a href="https://en.wikipedia.org/wiki/Workflow">process-flow</a>). and that's just <a title="By IDS.photos from Tiverton, UK [CC BY-SA 2.0 (http://creativecommons.org/licenses/by-sa/2.0)], via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File%3ACactus_close-up%2C_but_dont_get_too_close%2C_ouch!_(3225490111).jpg">needless pain</a>. needless for you and for anyone attempting to consume it. </p> <h4>tight coupling is trouble</h4> <p> tight coupling to any external component or service -- what i call a <i>fatal dependency</i> -- is big trouble. you don't want it. run away. how do you know if you have a fatal dependency? if some service or component you use changes and your code breaks -- that's <b>fatal</b>. it doesn't matter what code framework, software pattern, or architectural style you are using -- breakage is fatal -- stop it. </p> <h4>the circuit</h4> <p> you can stave off fatalities by wrapping calls to dependents in what <a href="https://twitter.com/mtnygard">Nygaard</a> calls in his book <a href="https://pragprog.com/book/mnee/release-it">Release It!</a> a <a href="http://martinfowler.com/bliki/CircuitBreaker.html">Circuit Breaker</a> but that requires you <i>also</i> have either 1) an alternate service provider (or set of them) or, 2) you write your code such that the unavailable dependency doesn't mean your code is essentially unusable (<i>"Sorry, our bank is unable to perform deposits today."</i>). and the Circuit Breaker pattern is not meant for use when services introduce <b>breaking changes</b> anyway -- it's for cases when the dependent service is <i>temporarily</i> unavailable. </p> <h4>a promise</h4> <p> you're much better off using services that make a promise to their consumers that any changes to that service will be non-breaking. IOW, changes to the interface will be only <i>additive</i>. no existing operations, arguments or process-flows will be taken away. this is not really hard to do -- except that existing tooling (code editors, build-tools, and testing platforms) make it really <i>easy</i> break that promise! </p> <blockquote> there are lots of refactoring tools that make it hard to break existing <i>code</i>, but not many focus on making it hard to break existing public <i>interfaces</i>. and it's rare to see testing tools that go 'red' when a public interface changes even though they are great at catching changes in private function signatures. bummer. </blockquote> <p>so you want to use services that keep the "no breaking changes" pledge, right? that means you also want to deploy services that make that pledge, too. </p> <h4>honoring the pledge</h4> <p> but how do you honor this "no breaking changes" pledge and still update your service with new features and bug fixes? it turns out that isn't very difficult -- it just takes some discipline. </p> <p>here's a quick checklist for implementing the pledge:</p> <dl> <dt>promise operations, not addresses</dt> <dd> service providers SHOULD promise to support a named operation (<code>shoppingCartCheckOut</code>, <code>computeTax</code>, <code>findCustomer</code>) instead of promising exact addresses for those operations (<code>http://myservice.example.org/findCustomer</code>). on the Web you can do that using properties like <code>rel</code> or <code>name</code> or <code>id</code> that have predetermined values that are well-documented. when this happens, clients can "memorize" the <i>name</i> instead of the address. </dd> <dt>promise message formats, not object serializations</dt> <dd> object models are bound to change -- and change often for new services. trying to get all your service consumers to learn and track all your object model changes is just plain wrong. and, even if you <i>wanted</i> all consumers to keep up with your team's model changes, that means your feature velocity is tied to the slowest consumer in your ecosystem - blech! instead, promise generic message formats that don't require an understanding of object models. formats like <a href="http://www.w3.org/TR/voicexml20/">VoiceXML</a> and <a href="http://amundsen.com/media-types/collection/">Collection+JSON</a> are specifically designed to support this kind of promise. <a href="http://www.w3.org/html/">HTML</a>, <a href="https://tools.ietf.org/html/rfc4287">Atom</a>, and other formats can be used in a way that maintains this promise, too. clients can now "bind" for the messgae format, not the object model -- changes to the model on the service don't leak out to the consumer. when this happens, adding new data elements in the response will not break clients. </dd> <dt>promise transitions, not functions</dt> <dd> service providers SHOULD treat all public interface operations as message-based <i>transitions</i>, not fixed functions with arguments. that means you need to give up on the classic <a href="https://en.wikipedia.org/wiki/Remote_procedure_call">RPC</a>-style implementation patterns so many tools lead you into. instead, publish operations that <i>pass messages</i> (using registered formats like <code>application/x-form-urlencoded</code>) that contain the arguments currently needed for that operation. when this happens, clients only need to "memorize" the argument names (all pre-defined in well-written documentation) and then pay attention to the transition details that are supplied in service responses. some "old skool" peeps call these transition details FORMs, but it doesn't matter what you call them as long as you promise to <i>use</i> them. </dd> <dt>promise dynamic process-flows, not static execution chains</dt> <dd> serivces SHOULD NOT promised fixed-path workflows ("I promise you will always execute steps X then A, then Q, then F, then be done."). this just leads consumers to hard code that nonsense into their app and break when you want to modify the workflow due to new business processes within the service. instead, services SHOULD promise a operation identifiers (see above) along with a limited set of process-flow identifiers (<code>start</code>, <code>next</code>, <code>previous</code>, <code>restart</code>, <code>cancel</code>, <code>done</code>) that work with <i>any</i> process-flow that you need to support. when this happens clients only need to "memorize" the generic process-flow keywords and can be coded to act accordingly. </dd> </dl> <h4>not complicated, just hard work</h4> <p> you'll note that all four of the above promises are not <a href="https://www.google.com/search?q=complicated+definition">complicated</a> -- and certainly not <a href="https://www.google.com/search?q=complex+definition"><i>complex</i></a>. but they do represent some <a title="By J. Howard Miller, artist employed by Westinghouse, poster used by the War Production Co-ordinating Committee [Public domain], via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File%3AWe_Can_Do_It!.jpg">hard work</a>. it's a bummer that tooling doesn't make these kinds of promises easy. in fact, most tools do the opposite. they make address-based, object-serialization with fixed argument functions and static execution chain easy -- in some tools these are the defaults and you just need to press "build and deploy" to get it all working. BAM! </p> <p> so, yeah. this job is not so easy. that's why you need to be diligent and disciplined for this kind of work. </p> <h4>eliminating dependencies</h4> <p> and -- back to the original point here -- decoupling addresses, operations, arguments, and process-flow means you eliminate lots of fatal dependencies in your system. it is now safer to make changes in components without so much worry about unexpected side-effects. and this will be a <b>big deal for all you microservice fans out there</b> because deploying dozens of independent services explodes your <i>interface-to-operation ratio</i> and it's just brutal to do that with tightly-coupled interfaces that <b>fail to support theses promises</b> inherent in a loosely-coupled implementation. </p> <h4>for the win</h4> <p> so, do not fear. whether you are a "microservice" lover or a "service-oriented" fan, you'll do fine as long as your make and keep these four promises. and, if you're a consumer of services, you now have some clear measures on whether the serivce you are about to "bind" to will result in fatalities in your system. </p>amazon, W3C and Tomorrow's Internethttp://www.amundsen.com/blog/archives/1161http://www.amundsen.com/blog/archives/1161Fri, 02 Oct 2015 21:36:00 GMT<p> <a href="http://fortune.com/2015/10/02/why-aws-users-should-care-that-amazon-nixed-apple-tv/"> <img src="https://fortunedotcom.files.wordpress.com/2015/09/fortune-a-1509014.jpg?quality=80&amp;w=840&amp;h=485&amp;crop=1" align="right" class="inline" width="150"/> </a> i'll make this brief and to the point: </p> <p> Amazon's <a href="http://fortune.com/2015/10/02/why-aws-users-should-care-that-amazon-nixed-apple-tv/">decision</a> to bar Google- and Apple-tv products from its store is both disturibing and, IMO, an indication that the <a href="http://www.w3.org/">W3C</a> is failing to live up to one of it's <a href="http://www.w3.org/Consortium/mission">key principles</a>. </p> <h4>Web For All</h4> <p> one of the key principles for W3C is the "Web for All" </p> <blockquote> The social value of the Web is that it enables human communication, commerce, and opportunities to share knowledge. One of W3C's primary goals is to make these benefits available to all people, whatever their hardware, software, network infrastructure, native language, culture, geographical location, or physical or mental ability. </blockquote> <p> when a single vendor has the power to block others' access to competitive products, the Web is a place that doesn't live up to this principle. I know that <a href="http://www.w3.org/People/Berners-Lee/">Tim Berners-Lee</a> is not <i>responsible</i> for the way Amazon operates. Neither is W3C CEO <a href="http://www.w3.org/People/Jeff/">Jeffery Jaffe</a>. however, this unfolding battle to pre-empt Web user's ability to access any content anywhere is just another iteration of the same battle that <a href="http://twitter.com/timberners_lee">timbl</a> (Berners-Lee's handle) has called out numerous times at the network level. what he calls the <a href="https://www.battleforthenet.com/">Battle For The Net</a>. </p> <h4>users over all others.</h4> <p> i know the W3C has attempted to <a href="https://www.w3.org/blog/2013/10/on-encrypted-video-and-the-open-web/">deal with this</a> in the past -- to mixed reviews. the very fact that Tim penned that piece on DRM and the Web shows that the W3C is aware of the issue. and a key part of that (now two-year-old) position paper was the notion of <a href="http://www.w3.org/TR/html-design-principles/#priority-of-constituencies">"users over all others"</a>: </p> <blockquote> In case of conflict, consider users over authors over implementors over specifiers over theoretical purity. </blockquote> <p> but events in this space seem to continue to run ahead of the W3C's ability to deal with them. and that's a big problem. </p> <h4>i know its hard, but it is important</h4> <p> i understand that the job of reigning in corporate greed on the open web is a tough job. and someone who has the best interests of users above all others needs to be <i>leading</i> the discussion. not following it. and certainly not silent while others establish the "operating rules" for yet another walled garden of profit built on the backbone of the free and <a href="http://www.w3.org/standards/">Open Web</a>. </p> <p> enabling commerce is a good thing. </p> <p> permitting exploitation and profiteering is not. </p> <h4>Tussle in Cyberspace</h4> <p> there is a great paper that deals with some of these issues: <a href="http://david.choffnes.com/classes/cs4700fa14/papers/tussle.pdf">Tussle in Cyberspace: Defining Tomorrow's Internet</a>. essentially: </p> <blockquote> This paper explores one important reality that surrounds the Internet today: different stakeholders that are part of the Internet milieu have interests that may be adverse to each other, and these parties each vie to favor their particular interests. We call this process “the tussle”. </blockquote> <p> the "tussle" is important. not because it <i>happens</i>, but because one of the key values of an open internet (not just Web) is that the Internet can be crafted (through standards) to "level the playing field" for all. this is why "Web For All" is important. this is why the Battle for the Net is important. </p> <p> and it is the same for video content, too. </p> <h4>why standards exist</h4> <p> we don't need to "regulate" vendors, we need to continue to make sure the tussle is fair to all. that's why standards exist -- <i>to level the playing field</i>. </p> <p> and, IMO, that's why the W3C exists. </p> <p> and that's why the current news is disturbing to me. </p>