mca bloghttp://www.amundsen.com/blog/making progressWed, 30 May 2012 18:24:45 GMTen-us180representin'http://www.amundsen.com/blog/archives/1129http://www.amundsen.com/blog/archives/1129Tue, 29 May 2012 20:48:00 GMT<p> <a href="http://www.flickr.com/photos/entropik/223028077/" title="rhizome"> <img src="http://farm1.staticflickr.com/84/223028077_6c4ae89cb5_q.jpg" align="right" class="inline" /> </a> <i>HTTP is the only <a href="http://en.wikipedia.org/wiki/Application_layer" title="Application layer"> application-level</a> protocol I know of that relies on the concept of "representations" as the primary way to transfer information between parties.</i> </p> <h4>discovery</h4> <p> i find myself repeating the above phrase relatively often lately. i noticed this aspect of HTTP many years ago. it greatly affected my thinking about the methodologies to employ when implementing solutions on the Web. once i grasped the notion that Web communications could exist at the abstraction of negotiable representations, a entirely new set of possiblities for improving the quality of communication were available to me. </p> <p><i>but then...</i></p> <h4>realization</h4> <p> i quickly realized that most of the frameworks and other tooling at my disposal when building Web solutions ignores this level of abstraction. IOW, while i have easy access to private component objects and data elements and a well-established pattern for exposing these private objects to the public (<a href="http://en.wikipedia.org/wiki/Serialization" title="Serialization">Serialization</a>), there are few common frameworks that make it easy to <i>represent</i> my private component details in one of the dozens of domain- and framework-agnostic registered <a href="http://www.iana.org/assignments/media-types/index.html" title="MIME Media Types">media types</a> designed for this very purpose. </p> <p>that means, each time i want to craft a representation of my private object to share on the public Web, i need to "hand-roll" my representation layers. to me, while annoying, i assumed that this was the price i had to pay in order to maintain the <a href="http://en.wikipedia.org/wiki/Separation_of_concerns" title="Separation of concerns">SoC</a> on the public Web that would allow me to safely interact w/ a wide range of clients and servers over time. </p> <p>i also assumed others took the same POV; that they, too, felt this pain and would (eventually) prod frameworks and tool providers to "add-in" support for the representation-level abstraction. </p> <p><i>but then...</i></p> <h4>discovery</h4> <p> it dawned on me (as i travelled around speaking, writing, and learning) that most devs i encountered didn't see things the same way i did. instead of "pining" for the SoC of representation abstractions, most devs simply accepted the status quo and assumed exposing private objects via serialization (and the perpetual wrestling match of keeping client object models and server object models in sync over time) was more than the norm, it was "the way to do things on the Web." in addition, to my <a href="http://www.thefreedictionary.com/chagrin" title="Defintion of chagrin">chagrin</a>, when i took the time to point out HTTP's <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12" title="12 Content Negotiation">representation abstraction</a> most devs either <a href="http://bitworking.org/news/WebServicesAndContentNegotiation" title="Should you use Content Negotiation in your Web Services?">denied it's usefulness</a> and/or decried it's implementation details as too complex to be worth the effort. </p> <p> few of those i spoke to even suggested that frameworks and tools should 'level up' and include proper support for the representation abstraction inherent in HTTP in order to remove these artifical barriers to improved communication options on the Web. </p> <p><i>so...</i></p> <h4>realization</h4> <p> i concluded that it is important to continue to write about. and advocate for, increased support for representation abstraction in Web tooling. i am pleased to see evidence of increased use of representations in implementations, too (check the trending download count over time on the very solid <a href="http://code.google.com/p/mimeparse/downloads/list" title="mimeparse">mimeparse</a> project). i'm happy to see popular frameworks adopting <a href="http://nicksda.apotomo.de/2011/12/ruby-on-rest-introducing-the-representer-pattern/" title="Ruby On REST: Introducing the Representer Pattern"> representation-as-a-pattern</a> and it's good to see at least one framework adopting <a href="http://codebetter.com/glennblock/2012/01/08/hypermedia-and-web-api-design-brain-dump-and-samples/" title="Hypermedia and Web API. Design brain dump and samples" >support</a> for the representation abstraction. </p> <p><i>but there is more work to be done...</i></p> <h4>discovery</h4> <p> as more people discover the power and possibility of <i>representing</i> domain-specific information in an implementation-agsnotic way, more Web solutions will exhibit the <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/net_app_arch.htm#sec_2_3_4_5">reusability</a>, <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/net_app_arch.htm#sec_2_3_4_2">extensibility</a>, and <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/net_app_arch.htm#sec_2_3_4_1">evolvability</a> (among other things) that can result when implementing distributed solutions for the Web. IMO, the "new" trend of <a href="http://en.wikipedia.org/wiki/Web_API" title="Web API">Web API</a>s will succeed (or fail) largely on the ability of tooling to support HTTP's representation abstraction. </p> <h4>realization</h4> <p><i>how well does your current set of frameworks and tools handle HTTP's representation abstraction?</i></p> a great WS-REST 2012 @ WWW2012http://www.amundsen.com/blog/archives/1128http://www.amundsen.com/blog/archives/1128Sat, 21 Apr 2012 09:44:00 GMT<p> <a href="http://ws-rest.org/2012/" title="WS-REST 2012"> <img src="http://www.ws-rest.org/2012/logo-wsrest2012.png" align="right" class="inline" width="175"/> </a> i had the honor and pleasure of presenting my paper "APIs to Affordances: A new paradigm for services on the Web" (<a href="http://ws-rest.org/2012/proc/a8-1-amundsen.pdf" title="APIs to Affordances: A new paradigm for services on the Web">paper</a>, <a href="http://g.mamund.com/pzmjh" title="APIs to Affordances: A new paradigm for services on the Web">slides</a>) at this year's WS-REST Workshop as part of <a href="http://www2012.wwwconference.org/">WWW 2012</a> in Lyon, France. i got some very good feedback during the review process and additional questions and comments at the workshop itself. it was great to be able to spend time with some of the very talented people working in the REST/HTTP Web services space. </p> <h4>papers</h4> <p> there were <a href="http://ws-rest.org/2012/program" title="WS-REST 2012 Program"> a number of very good papers</a> presented. instead of singly any out, i'll just encourage everyone to follow the link and check them out yourself. i also know that some of the papers will be updated by the end of April 2012. be sure to come back and pick up the latest editions after that date, too. </p> <p> more than one of the papers directly mentioned the issue of hypermedia transitions as part of the implementation/design of services on the Web. as my readers might expect, i find this encouraging. i've continued to work along lines that focus on moving past a read-only loosely-coupled Web toward a read-write Web while still maintaing a high degree of loose coupling. More than one paper showed specific work toward that aim. i look forward to the time when these kinds of implementations become not only common, but also as easily assumed as the notion of "a link" is today on the Web. </p> <p> of course, hypermedia was not the only focus of the papers. there are several on general modeling of services on the Web as well as two papers on applying aspects of the <a href="http://www.w3.org/standards/semanticweb/" title="Semantic Web"> Semantic Web</a> to services on the Web. </p> <h4>connections</h4> <p> another of the highlights of this year's event was the chance to renew ties to several people i first met in person at the <a href="http://www2010.org/www/index.html">WWW 2010</a> in Raleigh, NC. i aldo got the opportunity to put faces to the names and twitter handles with which i'd been interacting over the last two years. having the time to talk w/ the attendees, presenters, and the workshop organizers (<a href="https://twitter.com/ruyalarcon" title="@ruyalarcon">Rosa Alarcon</a>, <a href="https://twitter.com/pautasso" title="@pautasso">Cesare Pautasso</a>, and <a href="https://twitter.com/dret" title="@dret">Erik Wilde</a>) is real 'boost' for me. it's a chance to hear new points of view, explore details, and gain an added appreciation for the work of others. </p> <h4>WWW 2012</h4> <p> and, yes, there was a full program of keynotes, sessiopns, and panels for the WWW 2012 event. i really enjoyed the keynotes this year; especially the <a href="http://www2012.wwwconference.org/neelie-kroes/" title="">talk</a> by <a href="http://en.wikipedia.org/wiki/Neelie_Kroes" title="Neelie Kroes"> Neelie Kroes</a> on the role of government in aiding the growth &amp; safe-keeping of the Web. i also very much like the <a href="http://www2012.wwwconference.org/documents/Stiegler-www2012-keynote.pdf" title="The Aufklarung in the Age of Philosophical Engineering ">keynote</a> by <a href="http://www2012.wwwconference.org/bernard-stiegler/" title="Bernard Stiegler"> Bernard Stiegler</a> on the "Age of Philosophical Engineering; view of how the Web is affecting all of us; even our brains. </p> <p> all in all it was a good week; too bad it only happens once a year! </p> <p> BTW - maybe i'll see you at <a href="http://www2013.org/" title="WWW 2013">WWW2013</a> in Rio. </p>Whisky Web was greathttp://www.amundsen.com/blog/archives/1127http://www.amundsen.com/blog/archives/1127Sun, 15 Apr 2012 09:55:00 GMT<p> <a href="http://whiskyweb.co.uk/" title="Whisky Web Conference"> <img src="http://www.magmadigital.co.uk/assets/whisky-web-300x150.jpg" width="150" align="right" class="inline" /> </a> this weekend, i had the great pleasure of participating in the innagural <a href="http://whiskyweb.co.uk/">Whisky Web Conference</a> in Edinburgh, Scotland. what a great event! <a href="http://twitter.com/juokaz" title="@juokaz">Juozas (Joe) Kaziukenas</a> organized the event and it lived up to the description on the front page of the web site: </p> <blockquote> A web conference created for the web community, by the web community, Whisky Web will have something to offer everyone who works with the web, be they a designer, a developer or something in between. This is an amazing opportunity to get your geek on in Scotland's inspiring capital. </blockquote> <p> There are great keynotes by <a href="http://twitter.com/joshholmes" title="@joshholmes">Josh Holmes</a> and <a href="http://twitter.com/dzuelke" title="dzuelke">David Zuelke</a> as well as a fine list of talks by <a href="http://whiskyweb.co.uk/#speakers" title="Speakers"> very engaging speakers.</a> there was also a "Whisky Master Class" on the first evening presented by <a href="http://twitter.com/#!/whiskycraig" title="@whiskyCraig"> Craig Johnstone</a> of <a href="http://www.bruichladdich.com/">Bruichladdich Distillery</a>. four spirits to taste and lots of history and stories to go with them. Craig was quite entertaining. </p> <blockquote> <b>NOTE</b><br/> all the talks were recorded to video and should be available soon. i will post a link here when they are available. </blockquote> <p> in addition, the catering was solid and the venues were fantastic. the sessions were presented in <a href="http://en.wikipedia.org/wiki/The_Hub,_Edinburgh" title="The Hub">The Hub</a> at the top of the <a href="http://en.wikipedia.org/wiki/Royal_Mile" title="The Royal Mile"> Royal Mile</a> near <a href="http://en.wikipedia.org/wiki/Edinburgh_Castle" title=""> Edinburgh Castle</a>. the second day (the Hackathon) was hosted at the other end of the Royal Mile in a building called <a href="http://en.wikipedia.org/wiki/Our_Dynamic_Earth">Our Dynamic Earth</a> next to the <a href="http://en.wikipedia.org/wiki/Holyrood_Abbey">Hollyrood Abbey</a>. the facilites were excellent. </p> <p> i had the honor to present an updated version of my <a href="http://amundsen.com/talks/#essential-node"> Essential Node.js for Web Developers</a>. it was a well-attended session and there were some very good questions and comments afterwards. i also must admit i dipped out of the proceedings to tour <a href="http://en.wikipedia.org/wiki/St_Giles'_Cathedral"> St Giles' Cathedral</a> and to climb <a href="http://en.wikipedia.org/wiki/Calton_Hill">Calton Hill</a> to take in a high view of the city of Edinburgh. </p> <p> having ben involved (just a bit) in the "behind-the-scenes" of setting up and supporting a dev conference, i can say this effort was top notch all around. i am already setting plans for attending next year and encourage everyone to consider a trip to Edinburgh in spring of 2013 for some whisky and some web. </p> tangible RESThttp://www.amundsen.com/blog/archives/1125http://www.amundsen.com/blog/archives/1125Tue, 06 Mar 2012 12:43:00 GMT<p> <a href="http://www.flickr.com/photos/-followthemusic-/6758284027/" title="Tangible Light"> <img src="http://farm8.staticflickr.com/7008/6758284027_aa7098b036_t.jpg" align="right" class="inline" /> </a> last week <a href="https://twitter.com/#!/robconery" title="@robconery">Rob Conery</a> posted an <a href="http://wekeroad.com/2012/03/03/moving-the-philosophy-into-machinery/" title="Moving The Philosophy Into Machinery">invitation</a> on his blog asking people to "...jump in and write me up a [RESTful] API." what followed was some lively discussion in the comment stream on that post and (to date) produced <a href="http://www.bizcoder.com/index.php/2012/03/05/a-tekpub-api/" title="A Tekpub API">four</a> <a href="http://devlicio.us/blogs/rob_eisenberg/archive/2012/03/05/alt-tekpub-rest.aspx" title="Alt.Tekpub REST">sample</a> <a href="https://gist.github.com/1975080" title="mikekelly's gist 1975080">API</a> <a href="http://g.mamund.com/uwbry" title="Rob Conery's API Invitation">designs</a> for Rob to consider. </p> <p>that's pretty cool!</p> <h4>evidence of style</h4> <p> while each solution was different (they each reflect the designer's <i>style</i>), they are all evidence of attempts to provide a hypermedia-style solution to Rob's challenge. one of the things i like about all this is that it offers up tangible examples; not just theoretical discussion. since they are all actual examples, this also makes it possible to ask clear questions about what is shown; what is intended, why it exists, and what the expected results are for designing interfaces in this manner. </p> <p> so, from my POV, the real value here is not just in the resulting designs, but also in the public process of offering up real attempts at solutions for a real problem. </p> <h4>we need more of this</h4> <p> i think we need to see much more of this, too. the more physical examples we have the more we can learn from each other, the more we can ask informed questions about style choices and, the more we can compare designs to tease out helpful commonalitiesand differences. what we also need (IMO) are <i>running examples</i>; live implementations that we can also inspect, compare, and evauluate. but i'll leave that topic for another blog post. </p> <h4>oh, BTW - thanks Rob!</h4> <p> now how 'bout some more folks offer Rob a sample API? </p>Rob Conery's API Invitationhttp://www.amundsen.com/blog/archives/1124http://www.amundsen.com/blog/archives/1124Sat, 03 Mar 2012 17:37:00 GMT<blockquote> <b>2012-03-04 Update:</b><br /> there is a lively discussion in the comment section of Rob's <a href="http://wekeroad.com/2012/03/03/moving-the-philosophy-into-machinery/">blog post</a> (the one referred in my content below). be sure to check it out. </blockquote> <p> <a href="http://wekeroad.com/2012/03/03/moving-the-philosophy-into-machinery/"> <img src="http://wekeroad.com/wp-content/uploads/2012/03/cyclops.jpeg" width="150" align="right" class="inline" /> </a> this week <a href="https://twitter.com/#!/robconery" title="@robconery">Rob Conery</a> issued an <a href="http://wekeroad.com/2012/03/03/moving-the-philosophy-into-machinery/" title="Moving The Philosophy Into Machinery">invitation</a> to readers: </p> <blockquote> I would like to invite the good people who have engaged with me over the last few days to jump in and write me up an API. </blockquote> <p> he named some folks in paricular including <a href="https://twitter.com/#!/gblock" title="@gblock">Glenn Block</a>, <a href="http://twitter.com/kellabyte" title="@kellabyte">Kelly Sommers</a>, <a href="https://twitter.com/#!/darrel_miller" title="darrel_miller">Darrel Miller</a>, <a href="https://twitter.com/#!/icooper" title="@icooper">Ian Cooper</a>. and, even though i was not on "the list" i am offering up some possible examples anyway[grin]. </p> <p>turns out i had some free time during a commute last night and i took that time to whip up three possible interface examples. hopefully my contribution will spark some conversation and interest in the idea of designing Web APIs using <i>in-message hypermedia</i> instead of the common practice of limiting designs to mapping the problem domain directly to the HTTP protocol using URIs and protocol methods (more on that <a href="http://amundsen.com/blog/archives/1120" title="entities and actions">here</a>). </p> <blockquote> WARINING: i did these in a bit of a hurry so there will be some minor problems, i suspect. </blockquote> <h4>idle thoughts of a warped mind</h4> <p> i actually do these kinds of exercises quite often (almost daily). i see an application interface for the Web (a Web API, etc.) and my brain starts to sketch out how that might be done as a hypermedia interface. sometimes it's just data in my head. sometimes i scratch it out on loose paper, napkins, etc. that happen to by lying around. occassionaly, i pull up my handheld, laptop, etc. and pound out a doc for later. on a few occasions, i've even commited the design to disk w/ some scaffolding programming around it. </p> <p> so, anyway, here are three possible hypermedia interfaces for the scenario Rob described in his blog post. </p> <h4>XML Hypermedia API</h4> <p> this is proly the easiest example to 'grok', the affordances are plain, the processing instructions pretty easy to apply to the elements. this is really a set of 'invented' hypermedia affordances w/o reference to a registered media type, but it still works fine. sticklers will want an actual MIME Type identifer for this and i'll claim <code>application/vnd.conery+xml</code> as the one i will use. </p> <script src="https://gist.github.com/1964135.js?file=conery-api.xml"></script> <h4>JSON Hypermedia API</h4> <p> this one is proly the hardest to 'grok' upon reading. the affordances here are for a little-used registered JSON hypermedia type ( <a href="http://www.amundsen.com/media-types/collection/" title="Collection+JSON"> application/vnd.collection+json</a> which i designed myself about a year ago. it's similar to Atom, but in a JSON format that also includes support for ad hoc queries and a write template. </p> <script src="https://gist.github.com/1964134.js?file=conery-api.js"></script> <p> writing a client-side processor for this design is pretty straight-forward. i was able to build a quick one in JS and there is at least one in Java and Ruby, i think. </p> <h4>HTML Hypermedia API</h4> <p> using HTML as the API message base is really quite easy and has some key advantages. there is already a powerful processor client available (the common Web browser) and it's easy to "test" the API by just "surfing it" w/ a browser (thanks to <a href="https://twitter.com/#!/jon_moore" title="@jon_moore">Jon Moore</a> for teaching me that phrase). </p> <script src="https://gist.github.com/1964131.js?file=conery-api.html"></script> <p> writing a processor for HTML Hypermedia means writing a client that is smart enough to recognize the semantic markers in the message (@id, @name, @rel, @class) and 'behave' accordingly at runtime; not too tough at all. i always output HTML APIs in valid XHTML so it's even easy for desktop/console apps to use XML processor tools to parse the messages first. </p> <h4>Oh, there's more...</h4> <p> I didn't come up w/ an example using <a href="http://www.ietf.org/rfc/rfc4287" title="RFC4287">Atom</a> + <a href="http://tools.ietf.org/html/rfc5023" title="RFC5023">AtomPub</a>; that would be fairly easy, too. There is also <a href="http://stateless.co/hal_specification.html" title="Hypertext Application Language">HAL</a> which is another solid hypermedia design. i've even toyed w/ implementing a hypermedia design for <a href="http://en.wikipedia.org/wiki/Markdown" title="Markdown">Markdown</a>, <a href="http://yaml.org/" title="YAML">YAML</a>, or even <a href="http://www.rfc-editor.org/rfc/rfc4180.txt" title="RFC4180">CSV</a> but haven't gotten around to sketching that stuff out. </p> <p> So, there are some of my thoughts. how would <i>you</i> implement a REST API for Rob? </p>template for node workhttp://www.amundsen.com/blog/archives/1123http://www.amundsen.com/blog/archives/1123Fri, 02 Mar 2012 17:52:00 GMT<p> <a href="http://www.flickr.com/photos/wild-smith/2866078450/" title="Molding: Stage 1"> <img src="http://farm4.staticflickr.com/3086/2866078450_65e5b45686_t.jpg" align="right" class="inline" /> </a> starting to ramp up my node-er-ing and have settled into some personal habits/standards that help me get past the 'dross' and into the heart of the puzzles. </p> <p> so, i'll drop some of these items here in the blog as a way to 'out' my habits, get some feedback and refine my standards over time. </p> <h4>basic template for app.js</h4> <p> here's how i "start" my scripts: </p> <pre class="code"> /* hello, node */ // declare module to use var http = require('http'); // handle all requests function handler(req, res) { res.writeHead(200, 'OK',{'Content-Type':'text/plain'}); res.end('Hello, node! from '+ req.url); } // listen for requests http.createServer(handler).listen(process.env.PORT); </pre> <p> a three-part model: </p> <ol> <li>pull in requires</li> <li>set up listener to run "handler" when the event fires (at the bottom)</li> <li>supply the "handler" (as the actual function name)</li> </ol> <h4>some additional decoration</h4> <p> for non-trivial examples, i usually declare a module-level hash table (the use of the hash is a sanity check for my mental REPL when trying to resolve scope). </p> <p> i also write a <code>main();</code> to hold the routing logic or other high-level stuff. this is not needed, but again, keeps the code clean and sectioned off. </p> <pre class="code"> /* hello form */ // modules var http = require('http'); var querystring = require('querystring'); function handler(req, res) { var g = {}; g.url = '/'; g.textHtml = {'Content-Type':'text/html'}; g.form = '&lt;h1&gt;hello, form!&lt;/h1&gt;' + '&lt;form method="post" action="/" &gt;' + '&lt;label&gt;Email: &lt;/label&gt;' + '&lt;input name="email" type="email" value="" placeholder="user@example.org" required="true" /&gt;' + '&lt;input type="submit" /&gt;' + '&lt;/form>'; g.output = '&lt;h1&gt;hello, form!&lt;/h1&gt;' + '&lt;p&gt;{@email}&lt;/p&gt;' + '&lt;p&gt;&lt;a href="/"&gt;return&lt;/a&gt;&lt;/p&gt;' main(); function main() { if(req.url === g.url) { switch(req.method) { case 'GET': handleGet(); break; case 'POST': handlePost(); break; default: sendResponse(405, 'Method not allowed', '&lt;h1>405 - Method not allowed&lt;/h1>'); } } else { sendResponse(404, 'Not found', '&lt;h1>404 - Not found&lt;/h1>'); } } function handleGet() { sendResponse(200, 'OK', g.form); } function handlePost() { var body = ''; req.on('data', function(chunk) { body += chunk.toString(); }); req.on('end', function() { var results = querystring.parse(body); sendResponse(200, 'OK', g.output.replace('{@email}',results.email)); }); } function sendResponse(status, text, body) { res.writeHead(status, text, g.textHtml); res.end(body); } } http.createServer(handler).listen(process.env.PORT); </pre> <h4>comments, suggestions, warnings?</h4> <p> any feedback you wish to share? </p>POST-PUT-PATCH illustratedhttp://www.amundsen.com/blog/archives/1122http://www.amundsen.com/blog/archives/1122Thu, 01 Mar 2012 17:04:00 GMT<p> <a href="http://www.flickr.com/photos/limowreck666/124628254/" title="thats torn it"> <img src="http://farm1.staticflickr.com/44/124628254_a3b3494858_t.jpg" align="right" class="inline" /> </a> the announcement that <a href="http://weblog.rubyonrails.org/2012/2/26/edge-rails-patch-is-the-new-primary-http-method-for-updates"> Rails is adding support for PATCH</a> has caused some <a href="http://wekeroad.com/2012/02/28/someone-save-us-from-rest/">gum-flapping</a> on the Inter-Tubes and this all came up in a recent convo w/ some of my colleagues today. it turned out most of them don't have much experience in "talking HTTP" but know T-SQL really well. so i decided to illustrate the differences between HTTP's POST, PUT, and PATCH methods using simple T-SQL examples. </p> <p> it seemed to resonate w/ the folks in the room so i decided to share it here. now, my T-SQL is a bit stilted, but it get ths point across. </p> <p> hopefully, this illustration will spark some convos where you are and result in some deeper discussion and understanding of the HTTP protocol. </p> <h4>POST</h4> <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5"> HTTP.POST</a> can be used when the client is sending data to the server and the server will decide the URI for the newly created resource. <blockquote> "The POST method is used to request that the origin server accept the entity enclosed in the request as <b>a new subordinate</b> of the resource identified by the Request-URI in the Request-Line." </blockquote> <p> this is what most of us think of when we talk about "creating data" on a web server. translating this into T-SQL is really easy; just use an auto-incrementing primary key for INSERTS. </p> <pre class="code"> -- T-SQL version of POST CREATE TABLE [dbo].[PostToDo]( [ID] [int] IDENTITY(1,1) NOT NULL, [Task] [nvarchar](1024) NOT NULL, [Completed] [nvarchar](10) NULL ) ON [PRIMARY] -- Write ala POST CREATE PROCEDURE WritePostToDo @Task nvarchar(1024), @Completed nvarchar(10) AS BEGIN SET NOCOUNT ON; INSERT INTO PostToDo VALUES (@Task, @Completed) END -- Send some data WritePostToDo 'Write code', 'no' WritePostToDo 'Fix bugs', 'no' WritePostToDo 'Deploy to production', 'no' WritePostToDo 'Enjoy a beer', 'no' -- Check out the results SELECT * FROM PostToDo 1,'Write code', 'no' 2,'Fix bugs', 'no' 3,'Deploy to production', 'no' 4,'Enjoy a beer', 'no' </pre> <h4>PUT</h4> <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6">HTTP.PUT</a> can be used when the client is sending data to the the server and the client is determining the URI for the newly created resource. <blockquote> The PUT method requests that the enclosed entity be stored under the <b>supplied Request-URI</b>. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI. </blockquote> <p> yeah, so that's kinda dense but the basics are pretty clear: </p> <ul> <li>client must supply the ID</li> <li>if the resource exists, *replace* it with the inbound data</li> <li>if it doesn't exist, create a new one (assuming you can <em>do</em> that)</li> </ul> <p> so in T-SQL it just takes a bit more fiddling to determine if the record already exsits. if yes, do an UPDATE. if no, do an INSERT. </p> <pre class="code"> -- T-SQL vesrion of PUT CREATE TABLE [dbo].[PutToDo]( [ID] [int] NOT NULL, [Task] [nvarchar](1024) NOT NULL, [Completed] [nvarchar](10) NOT NULL ) ON [PRIMARY] -- Write ala PUT CREATE PROCEDURE WritePutToDo @ID int, @Task nvarchar(1024), @Completed nvarchar(10) AS BEGIN SET NOCOUNT ON; IF(SELECT COUNT(*) FROM PutToDo WHERE ID=@ID)=0 BEGIN INSERT INTO PutToDo VALUES (@ID, @Task, @Completed) END ELSE BEGIN UPDATE PutToDo SET Task=@Task, Completed=@Completed WHERE ID=@ID END --END IF SELECT * FROM PutToDo END -- Send some data WritePutToDo 1, 'write code', 'no' WritePutToDo 2, 'Fix bugs', 'no' WritePutToDo 3, 'Deploy to production', 'no' WritePutToDo 4, 'Enjoy a beer', 'no' -- Check out the results SELECT * FROM ToDo 1,'Write code', 'no' 2,'Fix bugs', 'no' 3,'Deploy to production', 'no' 4,'Enjoy a beer', 'no' -- Send some more data WritePutToDo 1,'write code','yes' -- Check out the results SELECT * FROM ToDo 1,'Write code', 'yes' 2,'Fix bugs', 'no' 3,'Deploy to production', 'no' 4,'Enjoy a beer', 'no' </pre> <h4>PATCH</h4> <a href="http://tools.ietf.org/html/rfc5789#section-2">HTTP.PATCH</a> can be used when the client is sending one or more changes to be applied by the the server. <blockquote> The PATCH method requests that <b>a set of changes</b> described in the request entity be applied to the resource identified by the Request-URI. The set of changes is represented in a format called a "patch document"... </blockquote> <p> now we get to have some fun! </p> <p> the spec clearly states this should involve a "patch document", not a typical resource write like in POST and PUT (interpret how you will...). anyway, the point is that PATCH is used to doing some kind of 'partial' update. </p> <p> translating this into T-SQL is not too tough. i decided to use a 'patch document' that consists of four things: </p> <ul> <li>ID of the record</li> <li>the FIELD to patch</li> <li>the OLDVALUE of the FIELD</li> <li>the NEWVALUE of the FIELD</li> </ul> <p> this allows the sproc to confirm that the field i want to modify has not already been modified by someone else since i last read in the data. that will cut down on problematic patches that might render the row invalid (again, interpret how you will...). </p> <pre class="code"> -- use the PutToDo Table definition -- Write ala PATCH CREATE PROCEDURE WritePatchToDo @ID int, @Field nvarchar(50), @OldValue nvarchar(1024), @NewValue nvarchar(1024) AS BEGIN SET NOCOUNT ON; IF(SELECT COUNT(*) FROM PutToDo WHERE ID=@ID)!=0 BEGIN IF(@Field='Task') BEGIN IF(SELECT Task from PutToDo WHERE ID=@ID)=@OldValue Update PutToDo SET Task=@NewValue WHERE ID=@ID --ENDIF END --ENDIF IF(@Field='Completed') BEGIN IF(SELECT Completed from PutToDo WHERE ID=@ID)=@OldValue Update PutToDo SET Completed=@NewValue WHERE ID=@ID --ENDIF END --ENDIF END --ENDIF END -- send some data WritePatchToDo 1, @Field='Task', @OldValue='write code',@NewValue='write buggy code' -- Check out results SELECT * FROM ToDo 1,'Write buggy code','yes' 2,'Fix bugs', 'no' 3,'Deploy to production', 'no' 4,'Enjoy a beer', 'no' </pre> <h4>does that help?</h4> <p> hopefully, seeing HTTP concepts translated to another form helps folks get a handle on the differences between these HTTP methods. T-SQL made sense to the group i was talking to at the time. i wonder if there are other "translations" that would be helpful, too. </p> <p> maybe you can show me? </p>essential node.js for web developershttp://www.amundsen.com/blog/archives/1121http://www.amundsen.com/blog/archives/1121Sun, 26 Feb 2012 20:29:00 GMT<p> <a href="http://cinnug.org/" title=""> <img src="http://cinnug.org/themes/cinnug/images/common/title.gif" width="165" align="right" class="inline" /> </a> i have the pleasure of presenting a talk at the <a href="http://cinnug.org/">CINNUG</a> user group meeting Tuesday, February 28th. the title of my talk is "<a href="http://amundsen.com/talks/#essential-node">Essential Node.js for Web Developers</a>" - one of my favorite topics of late! </p> <blockquote> <p> Unlike some introductions that spend time explaining event loops and web sockets, this session start with a typical "Hello, Node" demo and quickly moves to short, fully-functional apps that show how to deal with static files, POST forms, mashups from other servers, file manipulation, data-handling, and even supporting HTTP Authentication. </p> <p> If you need to get up-to-speed on Node.js really fast, or just want to get a great introduction to coding this powerful Web server, this talk is for you. </p> </blockquote> <p> since a native version of <a href="http://nodejs.org/">node</a> is now available on the Windows platform, node is poised to reach a wide audience and has the chance to make a big impact on the way we think about programming servers to support Web appliations. </p> <p> if you're interested in seeing what it's like to "code with node", come to the CINNUG meeting this Tuesday and check it out. </p> entities and actionshttp://www.amundsen.com/blog/archives/1120http://www.amundsen.com/blog/archives/1120Mon, 20 Feb 2012 10:24:00 GMT<p> <a href="http://www.flickr.com/photos/crartist/3073860476/" title="24/365 Face Off"> <img src="http://farm4.staticflickr.com/3141/3073860476_8e69fc1091_t.jpg" align="right" class="inline" /> </a> those who read my blog know that i favor a hypermedia style when implementing dist-net apps. i don't <em>always</em> use that style (it's not always the proper style for the problem at hand), but when i have the chance to <em>choose</em> which style i implement, hypermedia is often my selection. </p> <p> so that leads to an obvious question: "why?" </p> <p> while there are many reasons (too many to cover here), there is one aspect of the hypermedia style that i enjoy very much: it's "action" orientation. not "<a href="http://en.wikipedia.org/wiki/Event-driven_architecture">event-driven</a>" or "<a href="http://en.wikipedia.org/wiki/Behavior_based_AI">behavior-based</a>" but "action" orientation. </p> <h4>problem domains</h4> <p> when working with clients, there is a point (usually early on) where the talk focuses on the "problem domain"; the stuff that must get done. often this information is "bottled up" within the heads of selected members in the client company; sometimes it's well documented in policies &amp; and procedures documents. it can also appear as "source code" from some previous attempt at mapping the problem domain to computer code. this last method of expressing a problem domain is, IME, the least reliable as there have likely been several compromises (to fit the constraints of the coding environment) and often inaccurate translations (due to lack of understanding between the SME [subject matter expert] and the development team/person). </p> <p> anyway, through some means, the domain is exposed sufficiently to allow the work of mapping that domain onto the selected technology stack. in my case, this is almost always some form of mapping the domain to services running over HTTP. that's what i do most often and, at this point, i rarely get "called" unless the client has "pre-selected" for an HTTP implementation anyway[grin]. </p> <p> so, the next step is how to <em>go about</em> mapping the domain to HTTP. this is not the same as writing code; this is <em>before</em> code. this is the <em>design</em> or <em>architecture</em> part of the experience. and, since it is a design process, there are lots of possibilities, lots of tools, lots of methodologies, etc. and few can be accurately labeled as clearly "right" or "wrong." at this point, this is mostly about the preferences, and proclivities of the architect/designer. </p> <p> in my recent experience, there are two very common ways to approach this "mapping" task. one that focuses on the <em>entities</em> identified in the problem domain. another that focuses on the <em>actions</em> identified in the problem domain. there are other ways to view the domain (i.e. actors, components, etc.) but i'll focus on these two here: entites and actions. </p> <h4>action orientation</h4> <p> hypermedia designs focus on the actions taking place in the problem domain. things like "get a list of customers sorted by date" and "allow users to filter the order list by sales region" and "allow selected users to add new customers", etc. are all <em>actions</em>. when implementing a system using these actions as the centerpiece, hypermedia designs select the appropriate affordances (within the selected media type) and map those affordances to the identified actions. </p> <p>for example:</p> <dl> <dt>"get a list of customers by date"</dt> <dd> <code> <small> &lt;a href="..." rel="customers-by-date"&gt;Customers By Date&lt;/a&gt; </small> </code> </dd> <dt>"allow users to filter the orders list by sales region"</dt> <dd> <code> <small> &lt;form action="..." method="get" class="filter-orders"&gt;<br /> &lt;input name="region" value=""/&gt;<br /> &lt;/form&gt; </small> </code> </dd> <dt>"allow selected users to add new customers"</dt> <dd> <code> <small> &lt;form action="..." method="post" class="add-customer"&gt;...&lt;/form&gt; </small> </code> </dd> </dl> <p> in the above examples, the HTML.A and HTML.FORM affordances are used to provide the actions that map to the problem domain. note that hypermedia style implementations express the problem domain <em>within messages themselves</em>. this is an important point since it makes it possible to share this message in various ways and still retain the problem domain details (i.e. even <a href="http://www.amundsen.com/blog/archives/1041">if the message was sent via FTP</a>, the affordances could still work and still retain their usefulness). </p> <blockquote> the use of in-message affordances to carry the semantic details of the problem domain (instead of mapping the domain directly to the network protocol) is sometimes cited as a drawback of the hypermedia style. </blockquote> <p> you'll notice that the actual URIs for each affordance are of little interest here. in the hypermedia style, URIs are treated as nothing more than transient identifiers that enable the actions. hypermedia style implementations are prepared for (and fully expect) the moment when the URI for an affordance changes (for any number of reasons). that is one of the reasons the hypermedia style expresses problem domain details via messages instead of URIs. </p> <h4>entity orientation</h4> <p> entity designs focus on the entities or objects within the problem domain. for example "customers", "orders", etc. are <em>entities</em>. when implementing systems focused on entities, the most common methodology is to create network identities (URIs) that <em>contain</em> the entity names (i.e. http://example.org/<em>customers</em>/, etc.). implementors then use the high-level transfer protocol's network methods as "operators" for each entity. </p> <p>for example:</p> <dl> <dt>"get a list of customers by date"</dt> <dd> <code> <small> GET http://example.org/customers?order=date </small> </code> </dd> <dt>"allow users to filter the orders list by sales region"</dt> <dd> <code> <small> GET http://example.org/orders?region=... </small> </code> </dd> <dt>"allow selected users to add new customers"</dt> <dd> <code> <small> POST http://example.org/customers/ </small> </code> </dd> </dl> <p> in the above examples, instead of using a message format to carry the domain semantics, entity oriented designs map the domain directly onto the available protocol and attempt to make URIs themselves carry meaning. </p> <blockquote> entity orientation is similar to <a href="http://www.w3.org/RDF/">RDF</a> styles where the URI is treated as carrying intrinsic meaning and <em>is</em> the permanent identifier. </blockquote> <p> the appeal of this direct mapping of a problem domain to a network protocol is fairly obvious. it removes a layer of abstraction which exists for message-based hypermedia style. humans usually have little trouble mapping the limited set of HTTP protocol methods to simple operations on an "entity" (the classic <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">Create, Read, Update, Delete</a> === <a href="http://www.xml.com/pub/a/2004/12/01/restful-web.html">POST, GET, PUT, DELETE</a> meme). finally, this entity view is easy to support via "tooling" since it essentially reduces distributed network interactions to passing internal objects around using only four possible operations. </p> <p> but there are limits to this approach. first, entity orientation - while handy - is not how most humans think of life's interactions. usually they think first of the <a href="http://en.wikipedia.org/wiki/Seven_stages_of_action">goal they want to achieve</a> and then set up tasks in order to achieve it. second, it turns out to be quite difficult to get everyone to agree on the <a href="http://martinfowler.com/bliki/TwoHardThings.html">rules for forming identifiers</a>. the HTTP world has experienced <a href="http://www.w3.org/2001/tag/issues.html#httpRange-14">a decade-long dispute</a> over how to handle permantent network identifiers and it still is <a href="http://www.w3.org/wiki/HttpRange14Options">not sufficently settled</a>. </p> <p> finally, it happens that many real world cases do not map well to the limited set of HTTP methods. usually there are some suggested compromises on how to handle certain operations within the problem domain (using HTTP.POST to send large search criteria, etc.). <a href="http://en.wikipedia.org/wiki/WebDAV">WebDAV</a> solved this problem by adding <a href="http://www.webdav.org/specs/rfc4918.html#http.methods.for.distributed.authoring"> seven additional HTTP methods</a> that fit the targeted problem domain. </p> <h4>a matter of choice</h4> <p> in the end, it all boils down to choices. currently, implementing disitrubted network applications involves mapping the details of a problem domain to existing network standards. there is no getting around that; no choice there! but where we <em>do</em> have a choice is in how we go about accomplishing our task; the styles we use to map the domain to the standards. there are multiple ways to do this. i usually choose the hypermedia style since it tracks well with how i think about distributed networks, matches well with the existing strandards and technologies we use today ( <a href="http://tools.ietf.org/html/rfc3986">URIs</a>, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html">HTTP</a>, <a href="http://www.iana.org/assignments/media-types/index.html">IANA</a>) and presents very few restrictions when implementing clients and servers. </p> <p> what implementation style do you use? and why do you prefer it? </p>A resource is not the thing...http://www.amundsen.com/blog/archives/1119http://www.amundsen.com/blog/archives/1119Fri, 17 Feb 2012 11:43:00 GMT<p> <a href="http://www.flickr.com/photos/scottkinmartin/2196226089/" title="7 week old Huskimo Puppies"> <img src="http://farm3.staticflickr.com/2141/2196226089_d7f93b58b2_t.jpg" align="right" class="inline" /> </a> this continues to be one of my favorite quotes from <a href="http://roy.gbiv.com/">Roy Fielding</a>. it captures not just some details about the HTTP protocol, not just the heart of the problem w/ attempts to use URIs as permanent identifiers, but also a fundamental observation of how humans actually operate in the world. </p> <blockquote> <p> A resource is not the thing that is transferred across the wire or picked up off the disk or seen from afar while walking your dog. Each of those is only a representation. The same is true of physical objects encountered in life and never identified with URI and never made accessible on the net. Yes, it does present a bit of a quandary, but it is one that we have all learned to live with. Our eyes are not powerful enough to see identity through the representations, but our minds are powerful enough to associate identity to that which we see. Do I think of a different identifier every time I see my dog, or do I simply think of my dog as one identity and experience many representations of that identity over time (and on into memory and imagination)? </p> <p align="right"> <a href="http://lists.w3.org/Archives/Public/www-tag/2002Jul/0090.html"> Roy Fielding - July 2002 </a> </p> </blockquote> <p> this quote brings a smile to my face each time i read it. </p>