<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>nemetral.net &#187; Webdev</title>
	<atom:link href="http://nemetral.net/category/webdevelopment/feed/" rel="self" type="application/rss+xml" />
	<link>http://nemetral.net</link>
	<description>Insightful posts on design and code.</description>
	<pubDate>Mon, 18 May 2009 19:39:39 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The pursuit of APIness (part 7)</title>
		<link>http://nemetral.net/2008/07/24/the-pursuit-of-apiness-part-7/</link>
		<comments>http://nemetral.net/2008/07/24/the-pursuit-of-apiness-part-7/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 09:59:54 +0000</pubDate>
		<dc:creator>nemetral</dc:creator>
		
		<category><![CDATA[Webdev]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[business]]></category>

		<category><![CDATA[strategy]]></category>

		<guid isPermaLink="false">http://nemetral.net/?p=76</guid>
		<description><![CDATA[Already the seventh post of series "The pursuit of APIness", and it is now time to conclude by outlining another strategic issue substantially bound to APIs: local expertises. As a matter of fact, since the very goal of an API is to cross the line of existing web property (i.e. a website, a database) and open monitored accesses to data, releasing an API can make other websites orbitting in nearby niches use your API, i.e. use your data, i.e. transform your data into the local reference.


Related posts:<ol><li><a href='http://nemetral.net/2008/07/17/the-pursuit-of-apiness-part-6/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 6)'>The pursuit of APIness (part 6)</a> <small>The first five posts of series "The Pursuit of APIness"...</small></li><li><a href='http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 1)'>The pursuit of APIness (part 1)</a> <small>Say you need to upload a set of 100 pictures...</small></li><li><a href='http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 5)'>The pursuit of APIness (part 5)</a> <small>XML-RPC is damn easy to use and many projects still...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Already the seventh post of series &#8220;The pursuit of APIness&#8221;, and it is now time to conclude by outlining another strategic issue substantially bound to APIs: <strong>local expertises</strong>. As a matter of fact, since the very goal of an API is to cross the line of existing web property (i.e. a website, a database) and open monitored accesses to data, releasing an API can make other websites orbitting in nearby niches use your API, i.e. use your data, i.e. transform your data into <strong>the local reference</strong>.<span id="more-76"></span></p>
<h2>Part 7: Connecting local expertises</h2>
<p>&#8220;Local expertise&#8221; should not be understood as &#8220;geographically local&#8221; but as &#8220;expertise in a particular niche&#8221;. On top of being a <a href="http://en.wikipedia.org/wiki/Series_of_tubes">series of tubes</a>, the web is a <strong>tapestry of niches</strong> (e.g. &#8220;make money online&#8221;, &#8220;web 2.0 startups&#8221;, &#8220;reviews of gagdets&#8221;, &#8220;flash games&#8221;, &#8220;travel guides&#8221;, &#8220;maps&#8221; etc.). The goal for every webmaster is to make his/her website the leader in his/her particular niche.</p>
<p>Being a leader means having some influence on your followers or on other leaders. Now what&#8217;s the best way of having that kind of influence than making your followers use your data? Let&#8217;s take an example: <a href="http://techcrunch.com">Techcrunch</a>, the famous blog commenting the web 2.0 startups ecosystem, has quickly become one of the leader blogs in the niche (quite a tremendous amount of RSS subscriptions). They developed a whole blog network totalizing 15 websites so far, including an interesting project: <a href="http://crunchbase.com">Crunchbase</a>, a free and organized database containing updated information about startups and startup founders. In a nutshell, Crunchbase is to Techcrunch what <a href="http://freebase.com">Freebase</a> is to <a href="http://wikipedia.org">Wikipedia</a>: <strong>an organized abstraction of pure and cross-linked data</strong>. But Crunchbase goes even further: it is possible to embed Crunchbase information in any post, just like you can embed a <a href="http://youtube.com">Youtube</a> video in your blog or a <a href="http://www.scribd.com/">Scribd</a> document in your website (more information <a href="http://www.crunchbase.com/widget">here</a>).</p>
<p>Here is an example of Crunchbase widget for Flickr:</p>
<div class="cbw snap_nopreview">
<div class="cbw_header"><script src="http://www.crunchbase.com/javascripts/widget.js" type="text/javascript"></script></p>
<div class="cbw_header_text"><a href="http://www.crunchbase.com/">CrunchBase Information</a></div>
</div>
<div class="cbw_content">
<div class="cbw_subheader"><a href="http://www.crunchbase.com/company/flickr">Flickr</a></div>
<div class="cbw_subcontent"><script src="http://www.crunchbase.com/cbw/company/flickr.js" type="text/javascript"></script></div>
<div class="cbw_footer">Information provided by <a href="http://www.crunchbase.com/">CrunchBase</a></div>
</div>
</div>
<p>This is quite a smart move from Techcrunch: now blogs or websites in the same niche (or elsewhere) can directly embed Crunchbase data into their posts or pages. For Crunchbase data, it&#8217;s a <strong>first step outside</strong> through parameterizable widgets: it&#8217;s outside of Crunchbase&#8217;s official website, but the data is still enclosed in the widget&#8217;s HTML.</p>
<p><a href="http://www.techcrunch.com/2008/07/15/crunchbase-now-has-an-api-so-grab-our-data/">Recently</a>, Crunchbase released an <a href="http://www.crunchbase.com/help/api">API</a>. For Crunchbase data, that&#8217;s the <strong>second step outside</strong>, this time in <strong>complete freedom</strong> since developers can access pure JSON. Now third-party developers can build layers on top of Crunchbase data, which makes the latter a new <strong>reference</strong>. The example of Techcrunch is interesting: for it&#8217;s usually not easy to get accurate information about private equity fundings and acquisitions, opening access to a comprehensive and cleverly built database <strong>simplifies the developer&#8217;s life</strong> and, in a way, prevents him from <strong>reinventing the wheel</strong> (although it&#8217;s not exactly like an algorithm but it&#8217;s more of an information provider).</p>
<p>By extending its reach through widgets and an API, the Techcrunch network is aiming at becoming a comprehensive reference i.e., in the hot web 2.0 startups niche, a <strong>local expert</strong>. They&#8217;re not alone though: seeing the threat coming, ReadWriteWeb recently launched its own <a href="http://readwriteweb.tradevibes.com/">companies database</a> too.</p>
<p>Still, the strategy can&#8217;t only consist in opening wide access to core data: there is an equilibrium to find between locking all the data (bad move: competitors opening their data could reach your audience) and granting full access to it (bad move too: competitors could artificially bloat by absorbing your content or bury your web application under several layers of mashups).</p>
<h2>From APIs to mashups</h2>
<p>For an application, a blog or any website, releasing an API may help becoming a local expert. For third-party developers, using APIs makes it possible to <strong>connect local expertises</strong>.</p>
<p>Say you want to build a cool webapp (who doesn&#8217;t?) and provide users with geolocalized pictures of places they&#8217;ve been to. The easiest and best way to do so would certainly be to use existing services through their APIs:</p>
<ul>
<li><a href="http://facebook.com">Facebook</a> for profile data and places where the user has been (requires the user&#8217;s permission)</li>
<li><a href="http://flickr.com">Flickr</a> to find the pictures</li>
<li><a href="http://maps.google.com">GoogleMaps</a> to display the pictures in a neat map of the world.</li>
</ul>
<p>The service could work as follows:</p>
<ol>
<li>the user signs up and grants access to his Facebook profile data</li>
<li>your web application parses his/her profile and finds relevant places,</li>
<li>then gets photos from Flickr tagged with these places (and gets geolocalization too),</li>
<li>then create a custom GoogleMap with pictures on it,</li>
<li>and displays it back to the user for him/her to interact</li>
</ol>
<p>Here is a schema to better understand this example of a connection between <strong>local expertises</strong> (namely expertises in profile data, photos and maps):</p>
<p><img class="alignnone size-full wp-image-75" title="200807-web-apis-connect-local-expertise" src="http://nemetral.net/wp-content/uploads/200807-web-apis-connect-local-expertise.png" alt="" width="500" height="328" /></p>
<h2>Conclusion</h2>
<p>Through this series of posts, we&#8217;ve been reviewing APIs both on technical and business sides. In these intense times when every hour could bring you a new competitor from the other end of the world willing to lead your niche, it is important to build the basements of your user base and, if your business allows you to release an API, to do so and extend your reach.</p>
<p>A lot of nice people are here to help you building your API:</p>
<ul>
<li>experts such as Google&#8217;s Joshua Bloch (and his famous <a href="http://www.scribd.com/doc/33655/How-to-Design-a-Good-API-and-Why-it-Matters">keynote</a> on APIs)</li>
<li>companies such as <a href="http://mashery.com">Mashery</a>, specialized in helping you rolling out your own API</li>
<li>more advanced tutorials on how to design your own API (now that <a href="http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/">REST</a>, <a href="http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/">XML-RPC</a> and <a href="http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/">SOAP</a> are understood)</li>
<li>tons of classified APIs at <a href="http://www.programmableweb.com/">ProgrammableWeb</a> for you to get inspiration<a href="http://www.programmableweb.com/"><br />
</a></li>
</ul>
<p>I sincerely hope you enjoyed this series of posts. Please feel free to leave a comment!</p>


<p>Related posts:<ol><li><a href='http://nemetral.net/2008/07/17/the-pursuit-of-apiness-part-6/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 6)'>The pursuit of APIness (part 6)</a> <small>The first five posts of series "The Pursuit of APIness"...</small></li><li><a href='http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 1)'>The pursuit of APIness (part 1)</a> <small>Say you need to upload a set of 100 pictures...</small></li><li><a href='http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 5)'>The pursuit of APIness (part 5)</a> <small>XML-RPC is damn easy to use and many projects still...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://nemetral.net/2008/07/24/the-pursuit-of-apiness-part-7/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The pursuit of APIness (part 6)</title>
		<link>http://nemetral.net/2008/07/17/the-pursuit-of-apiness-part-6/</link>
		<comments>http://nemetral.net/2008/07/17/the-pursuit-of-apiness-part-6/#comments</comments>
		<pubDate>Thu, 17 Jul 2008 21:41:39 +0000</pubDate>
		<dc:creator>nemetral</dc:creator>
		
		<category><![CDATA[Webdev]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[strategy]]></category>

		<guid isPermaLink="false">http://nemetral.net/?p=59</guid>
		<description><![CDATA[The first five posts of series "The Pursuit of APIness" went through technical examples of how APIs actually work, from an illustration of how to hack a web form with a PHP script to how to design and program an API using custom XML, or following the REST principles, or using XML-RPC or SOAP. It is now time to wrap up everything we've learnt about web APIs and to understand why they're so strategic.


Related posts:<ol><li><a href='http://nemetral.net/2008/07/24/the-pursuit-of-apiness-part-7/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 7)'>The pursuit of APIness (part 7)</a> <small>Already the seventh post of series "The pursuit of APIness",...</small></li><li><a href='http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 2)'>The pursuit of APIness (part 2)</a> <small>Last week we looked at web forms and we observed...</small></li><li><a href='http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 5)'>The pursuit of APIness (part 5)</a> <small>XML-RPC is damn easy to use and many projects still...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>The first five posts of series &#8220;The Pursuit of APIness&#8221; went through technical examples of how APIs actually work, from an illustration of <a href="http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/">how to hack a web form with a PHP script</a> to how to <a href="http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/">design and program an API using custom XML</a>, or <a href="http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/">following the REST principles</a>, or using <a href="http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/">XML-RPC</a> or <a href="http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/">SOAP</a>. It is now time to wrap up everything we&#8217;ve learnt about web APIs and to understand why they&#8217;re so strategic.<span id="more-59"></span></p>
<h2>Part 6: Web APIs strategy</h2>
<p>APIs are a fantastic way to make computers talk together and build great business layers on top of other business layers on top of etc.  On the human side of the world, where things tend to be less binary, APIs represent a two-way strong strategic tool (&#8221;two-way&#8221; because releasing an API impacts both the original developers of a webapp and third-party developers building a third-party webapp).</p>
<p>Let&#8217;s start with the third-party developer&#8217;s view. In the <a href="http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/">first post</a> of this series, we considered a fictitious dude named Joe, willing to programmatically get data out of a website called community.com (fictitious website). For him, as for any third-party webdeveloper, using an API is great because it allows to:</p>
<ul>
<li><strong>backup existing data</strong>: say Joe is not confident in the future of community.com, he can programmatically backup his data stored in there through the API</li>
<li><strong>leverage existing data</strong> and, for example, display it in a more innovative way: Joe could build a great third-party application relying on community.com&#8217;s API and showing an interactive US map with the members&#8217; names updated in real time</li>
<li><strong>catch new users</strong>: say Joe builds this app, then (at least!) a percentage of original community.com users will be interested in it and will start using it</li>
<li><strong>unload some server resources</strong>: some web services do things well and fast, so why bother reinventing the wheel and consume server resources? For example, you could save storage for your pictures by using <a href="http://www.flickr.com/services/api/">Flickr&#8217;s API</a> (or <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/">Amazon S3&#8217;s</a>), you could create charts using <a href="http://code.google.com/apis/chart/">Google&#8217;s Chart API</a> etc.</li>
</ul>
<p>If we look at things from community.com&#8217;s point of view, releasing an API is a strong signal and should be part of a well-thought strategy, aimed at:</p>
<ul>
<li><strong>extending reach</strong> by bringing in new users from third-party apps using his/her API (there&#8217;s a mutually beneficial exchange of users between the original application and the third-party application, each one becoming a new entry point for the other)</li>
<li><strong>becoming a local expert</strong>: this is a really important point which will be analysed in the next (and last) post of this series; in a nutshell, releasing a clever API can <strong>erase competition from your niche</strong></li>
<li><strong>fighting against web scraping</strong>: third-party webdevelopers would now have an official and documented way to get data out of an application (of course they can still keep on <a href="http://en.wikipedia.org/wiki/Web_scraping">scraping your web pages</a> but releasing an API greatly simplifies their lives and encourages them to keep to the straight and narrow)</li>
</ul>
<h2>API design</h2>
<p>When releasing an API, developers should follow a comprehensive checklist to ensure third-party developers will start using it smoothly. In particular, it is essential to:</p>
<ul>
<li><strong>offer the widest range of protocols</strong>: some developers love REST, so you have to release a <a href="http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/">RESTful version or your API</a>; some other developers can&#8217;t live without XML-RPC so open a <a href="http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/">XML-RPC access</a> to them; some other have existing libraries built for SOAP so <a href="http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/">release a SOAP API</a>; some other love JSON so build a custom &#8220;JSON-RPC&#8221; API for them etc.</li>
<li><strong>document all the API&#8217;s functions for every protocol</strong>: yes, this is a <strong>huge work</strong> and this is were you will spend most of your time; documentation is key and the clearer it is, the more developers will use you API. Check out <a href="http://www.flickr.com/services/api/">Flickr</a>&#8217;s or <a href="http://developers.facebook.com/documentation.php">Facebook</a>&#8217;s APIs documentation: they&#8217;re real jowels for webdevelopers, filled with substantial code snippets helping them to get quickly started with the API.</li>
<li><strong>version your API</strong>: remember that once released, an API is <strong>forever</strong>. This means you can&#8217;t go backwards and change existing functions in your API because this would be a disaster for third-party applications built upon it and, therefore, for your users and your reputation. With an API, you can only go <strong>onwards</strong>. So it is extremely important to explicitly define versions for your API, for example by inserting version numbers right in the URL</li>
<li><strong>make it secure</strong>: web APIs have to be secure, both <strong>technically</strong> and <strong>strategically</strong>. Technically because accessing the data should happen the way it was meant to be without disrupting existing processes on the server or causing mess in the database. Strategically because releasing a web API is opening a documented door to the very heart of your <strong>content</strong>. An easy way to enhance security for your API is to release <strong>API keys</strong>: third-party developers have to request a key (usually a hash-like sequence of digits and letters) and then explicitly show this key in every single call made through the API. Doing so allows you to better monitor traffic and usage of your API.</li>
<li><strong>anticipate traffic surge</strong>: releasing an API means facing traffic spikes and, if everything goes well, facing a <strong>global increase in the load</strong>. It is crucial to anticipate this and avoid outages.</li>
</ul>
<h2>Protecting web property</h2>
<p>Here is a simple schema to better understand what&#8217;s going on when releasing an API:</p>
<p><img class="alignnone size-full wp-image-74" title="200807-power-of-web-apis" src="http://nemetral.net/wp-content/uploads/200807-power-of-web-apis.png" alt="" width="500" height="306" /></p>
<p>In this example, <strong>website 1</strong> is the usual interface developed to display the data (for example: website 1 is http://community.com displaying the community.com data). <strong>Website 2</strong> is a parallel website accessing community.com&#8217;s data but not developed by community.com. For example, it&#8217;s an aggregator designed to consolidate profiles from different online communities. For community.com, releasing a web API is interesting to extend its reach and bring in new users (for example, users of the aggregator service at website 2 who didn&#8217;t know about website 1 until they discover some of its members) but it also means organizing a documented data leak towards third-party apps, hence the need to focus on technical and strategic security.</p>
<p>The pursuit of APIness continues next week (last episode will be part 7). Stay tuned!</p>
<p><em>(go to Part 7: <a href="http://nemetral.net/2008/07/24/the-pursuit-of-apiness-part-7/">Connecting local expertises</a>)<br />
</em></p>


<p>Related posts:<ol><li><a href='http://nemetral.net/2008/07/24/the-pursuit-of-apiness-part-7/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 7)'>The pursuit of APIness (part 7)</a> <small>Already the seventh post of series "The pursuit of APIness",...</small></li><li><a href='http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 2)'>The pursuit of APIness (part 2)</a> <small>Last week we looked at web forms and we observed...</small></li><li><a href='http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 5)'>The pursuit of APIness (part 5)</a> <small>XML-RPC is damn easy to use and many projects still...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://nemetral.net/2008/07/17/the-pursuit-of-apiness-part-6/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The pursuit of APIness (part 5)</title>
		<link>http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/</link>
		<comments>http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 14:28:42 +0000</pubDate>
		<dc:creator>nemetral</dc:creator>
		
		<category><![CDATA[Webdev]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[http]]></category>

		<category><![CDATA[soap]]></category>

		<guid isPermaLink="false">http://nemetral.net/?p=63</guid>
		<description><![CDATA[XML-RPC is damn easy to use and many projects still rely on it. But for a few years a new protocol has emerged: SOAP. SOAP is traditionally considered as an evolution of XML-RPC. Selected by Google for its famous Search API (now deprecated), the SOAP protocol is usually considered as more complex than plain XML-RPC messaging. In fact, if you understood XML-RPC, then you should have no difficulty to understand SOAP as well, the latter being mainly an abstraction of XML-RPC.


Related posts:<ol><li><a href='http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 4)'>The pursuit of APIness (part 4)</a> <small>Last week we reviewed the principles behind a RESTful architecture....</small></li><li><a href='http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 1)'>The pursuit of APIness (part 1)</a> <small>Say you need to upload a set of 100 pictures...</small></li><li><a href='http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 2)'>The pursuit of APIness (part 2)</a> <small>Last week we looked at web forms and we observed...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>XML-RPC is damn easy to use and many projects still rely on it. But for a few years a new protocol has emerged: <strong>SOAP</strong>. SOAP is traditionally considered as an evolution of XML-RPC. Selected by Google for its famous Search API (now deprecated), the SOAP protocol is usually considered as more complex than plain XML-RPC messaging. In fact, if you understood XML-RPC, then you should have no difficulty to understand SOAP as well, the latter being mainly an abstraction of XML-RPC.<span id="more-63"></span></p>
<h2>Part 5: SOAP: Hot or not?</h2>
<p>Like XML-RPC, <strong>SOAP</strong> is a protocol for XML messaging over HTTP. Let&#8217;s start with the basic structure of a SOAP message (without HTTP headers for the moment):</p>
<pre>&lt;?xml version="1.0"?&gt;
&lt;soap:Envelope
  xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
  soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"&gt;
  &lt;soap:Header&gt;
    ...
  &lt;/soap:Header&gt;
  &lt;soap:Body&gt;
    ...
  &lt;/soap:Body&gt;
&lt;/soap:Envelope&gt;</pre>
<p><em>Note: as you can see, a SOAP message is made of an <strong>Envelope</strong> containing an <strong>optional Header</strong> and a <strong>mandatory Body</strong>. No need to get crazy about namespaces: you can basically chose your own namespace for any SOAP request. Look at the elements of the Envelope tag: in this example we chose &#8220;soap&#8221; and we had to tell that this &#8220;soap&#8221; namespace follows some standards (the two lines literally mean &#8220;the &#8217;soap&#8217; namespace we use has to be considered to be in the normal SOAP namespace&#8221; and &#8220;the &#8217;soap&#8217; namespace follows some standards for data types&#8221;). Instead of soap, we could have used &#8220;SOAP-ENV&#8221;, &#8220;env&#8221;, &#8220;s&#8221; as well as &#8220;mynameisjoe&#8221;. The important thing here is only to declare the namespace.</em></p>
<p>Now let&#8217;s look at a more realistic SOAP request with HTTP headers and with a different namespace for the envelope, let&#8217;s say a mere &#8220;s&#8221; as used for the Flickr API. The <code>Header</code> element being optional, we won&#8217;t use it here:</p>
<pre>POST /soap HTTP/1.1
Host: api.community.com
User-agent: script
Content-type: text/xml
Content-length: <span id="lblLength">332</span>

&lt;?xml version="1.0"?&gt;
&lt;s:Envelope
  xmlns:s="http://www.w3.org/2003/05/soap-envelope"
  s:encodingStyle="http://www.w3.org/2003/05/soap-encoding"&gt;
  &lt;s:Body&gt;
    &lt;a:GetMembersList xmlns:a="http://api.community.com/soap"&gt;
      &lt;age&gt;23&lt;/age&gt;
      &lt;city&gt;Indianapolis&lt;/city&gt;
    &lt;/a:GetMembersList&gt;
  &lt;/s:Body&gt;
&lt;/s:Envelope&gt;</pre>
<p><em>Note: as you can see, the HTTP headers must have a <strong>Host</strong>, a <strong>User-agent</strong> and a <strong>Content-type</strong> set to <code>text/xml</code>. Now look inside the <strong>Body</strong> element: what lies there is application-specific data which has to be identified using a different namespace (here we used the SOAP API&#8217;s entry point of website community.com). Developers have complete freedom to define what goes inside. Here we chose namespace &#8220;a&#8221; for all this application-specific data and we described which method had to be called (i.e. <code>GetMembersList</code>) along with parameters <code>age</code> and <code>city</code>.</em></p>
<p>So far we have seen the basic structure of a SOAP request. Now here is what the SOAP response could look like:</p>
<pre>HTTP/1.1 200 OK
Content-type: text/xml
Content-length: 391

&lt;?xml version="1.0"?&gt;
&lt;s:Envelope
  xmlns:s="http://www.w3.org/2003/05/soap-envelope"
  s:encodingStyle="http://www.w3.org/2003/05/soap-encoding"&gt;
  &lt;s:Body&gt;
    &lt;a:GetMembersListResponse xmlns:a="http://api.community.com/soap"&gt;
      &lt;members&gt;
        &lt;member&gt;Anna&lt;/member&gt;
        &lt;member&gt;Lisa&lt;/member&gt;
      &lt;/members&gt;
    &lt;/a:GetMembersListResponse&gt;
  &lt;/s:Body&gt;
&lt;/s:Envelope&gt;</pre>
<p><em>Note: few things have changed in the response. The method name has changed (following the usual convention of appending &#8220;<strong>Response</strong>&#8221; to the request&#8217;s method name) and the <strong>appication-specific data</strong> has changed too (it now returns the names of the two members aged 23 and living in Indianapolis)</em>.<em> Apart from that, all the namespaces and definition thing remains the same.</em></p>
<p>Keep in mind that SOAP is all about <strong>abstraction</strong> and that its complexity is the price for its flexibility. For example, we chose to design the application-specific data inside the first childnode (by calling it a:GetMembersList) but we could have decided as well to specify it along with the data in the following way (the Flickr way):</p>
<pre>&lt;a:Request xmlns:a="http://api.community.com/soap"&gt;
  &lt;method&gt;GetMembersList&lt;/method&gt;
  &lt;members&gt;
    &lt;member&gt;Anna&lt;/member&gt;
    &lt;member&gt;Lisa&lt;/member&gt;
  &lt;/members&gt;
&lt;/a:Request&gt;</pre>
<p>In the request example above, we did not specify data types for the parameters we sent along with the request. Without going too much into details, here is the way to specify that <code>&lt;age&gt;</code> is an integer and <code>&lt;city&gt;</code> a string:</p>
<pre>POST /soap HTTP/1.1
Host: api.community.com
User-agent: script
Content-type: text/xml
Content-length: <span id="lblLength">482</span>

&lt;?xml version="1.0"?&gt;
&lt;s:Envelope
  xmlns:s="http://www.w3.org/2003/05/soap-envelope"
  s:encodingStyle="http://www.w3.org/2003/05/soap-encoding"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  &gt;
  &lt;s:Body&gt;
    &lt;a:GetMembersList xmlns:a="http://api.community.com/soap"&gt;
      &lt;age xsi:type="xsd:int"&gt;23&lt;/age&gt;
      &lt;city xsi:type="xsd:string"&gt;Indianapolis&lt;/city&gt;
    &lt;/a:GetMembersList&gt;
  &lt;/s:Body&gt;
&lt;/s:Envelope&gt;</pre>
<p><em>Note: as you can see we need two more specifications defined as attributes of the Envelope tag. First we need to defined the namespace for XML Schema Instance and then the namespace for XML Schema Datatypes, and then we have to add the corresponding attributes to the <code>&lt;age&gt; </code>and <code>&lt;city&gt;</code> tags (the latter step being quite self-explanatory).</em></p>
<p>That&#8217;s it for this introduction to <strong>SOAP</strong>. So.. <em><strong>hot or not</strong></em>?</p>
<p>In many cases, SOAP is just bloated XML-RPC. If you can stick to XML-RPC then do it; no need to start using SOAP. On the other hand, if you want to expand the reach of your API or if you need very specific data types for your requests and responses, then go for SOAP. The final choice usually depends on the available libraries: as SOAP is more complex to manipulate, using a good library becomes more important than for XML-RPC where you can go down to making your PHP script directly spit the XML.</p>
<p><em>(go to <a href="http://nemetral.net/2008/07/17/the-pursuit-of-apiness-part-6/">Part 6: Web APIs strategy</a>)</em></p>


<p>Related posts:<ol><li><a href='http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 4)'>The pursuit of APIness (part 4)</a> <small>Last week we reviewed the principles behind a RESTful architecture....</small></li><li><a href='http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 1)'>The pursuit of APIness (part 1)</a> <small>Say you need to upload a set of 100 pictures...</small></li><li><a href='http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 2)'>The pursuit of APIness (part 2)</a> <small>Last week we looked at web forms and we observed...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The pursuit of APIness (part 4)</title>
		<link>http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/</link>
		<comments>http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 14:09:22 +0000</pubDate>
		<dc:creator>nemetral</dc:creator>
		
		<category><![CDATA[Webdev]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[http]]></category>

		<category><![CDATA[xmlrpc]]></category>

		<guid isPermaLink="false">http://nemetral.net/?p=62</guid>
		<description><![CDATA[Last week we reviewed the principles behind a RESTful architecture. This week, as part 4 of this series dedicated to web APIs, we will focus on XML-RPC which, contrary to REST, is not a set of general principles but a substantial specification on how to format XML messages carried over HTTP.


Related posts:<ol><li><a href='http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 2)'>The pursuit of APIness (part 2)</a> <small>Last week we looked at web forms and we observed...</small></li><li><a href='http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 3)'>The pursuit of APIness (part 3)</a> <small>In part 2, we saw how could be designed an...</small></li><li><a href='http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 5)'>The pursuit of APIness (part 5)</a> <small>XML-RPC is damn easy to use and many projects still...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Last week we reviewed the principles behind a <a href="http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/">RESTful architecture</a>. This week, as part 4 of this series dedicated to web APIs, we will focus on XML-RPC which, contrary to REST, is not a set of general principles but a substantial <strong>specification </strong>on how to format XML messages carried over HTTP.<span id="more-62"></span></p>
<h2>Part 4: Review of XML-RPC</h2>
<p><strong>XML-RPC</strong> stands for XML Remote Procedure Call: a XML-RPC request is a <strong>HTTP POST request</strong> which body is formatted in <strong>XML</strong> and a XML-RPC response is a XML file sent back by the server. Contrary to REST, the method called by a XML-RPC request does not appear in the URL but appears in the XML POST body of the request, in-between tags <code>&lt;methodName&gt;</code>. Therefore, XML-RPC works based on a <strong>single entry point</strong> which is the unique URL to be called when using XML-RPC.</p>
<p>Before we dive into the XML-RPC specifications, here is how our favorite call (<a href="http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/">Joe</a>&#8217;s call) to community.com&#8217;s API could be designed:</p>
<pre>POST /xmlrpc HTTP/1.1
Host: api.community.com
User-agent: script
Content-type: text/xml
Content-length: <span id="lblLength">243</span>

&lt;?xml version="1.0"?&gt;
&lt;methodCall&gt;
  &lt;methodName&gt;community.members.getList&lt;/methodName&gt;
  &lt;params&gt;
    &lt;param&gt;&lt;value&gt;&lt;int&gt;23&lt;/int&gt;&lt;/value&gt;&lt;/param&gt;
    &lt;param&gt;&lt;value&gt;&lt;string&gt;Indianapolis&lt;/string&gt;&lt;/value&gt;&lt;/param&gt;
  &lt;/params&gt;
&lt;/methodCall&gt;</pre>
<p><em>Note: several details matter in this sample request. First, we decided to use  <code>http://api.community.com/xmlrpc/</code> as the single entry point. Then, XML-RPC <strong>requires</strong> a User-agent (can be the name of the library you&#8217;re using, the name of your script or the name of your dog <img src='http://nemetral.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) and a Content-type set to <strong>text/xml</strong>. Last, method names must be <strong>unique</strong>: had we simply called this method <strong>getList</strong>, we could have faced difficulties when designing the call to retrieve, for example, cities instead of members. This is why we prepended the method name with <strong>community.members</strong> so as to be aware that we are using community.com&#8217;s API and that we are looking for members.<br />
</em></p>
<p>And here would be the successful response:</p>
<pre>HTTP/1.1 200 OK
Date: Tue, 01 Jul 2008 15:22:00 GMT
Content-Length: <span id="lblLength">313</span>
Content-Type: text/xml
Connection: close

&lt;?xml version="1.0"?&gt;
&lt;methodResponse&gt;
  &lt;params&gt;
    &lt;param&gt;
      &lt;value&gt;
        &lt;array&gt;
          &lt;data&gt;
            &lt;value&gt;&lt;string&gt;Anna&lt;/string&gt;&lt;/value&gt;
            &lt;value&gt;&lt;string&gt;Lisa&lt;/string&gt;&lt;/value&gt;
          &lt;/data&gt;
        &lt;/array&gt;
      &lt;/value&gt;
    &lt;/param&gt;
  &lt;/params&gt;
&lt;/methodResponse&gt;</pre>
<p>Now if we assume there was some issues while transmitting or processing the request, here is how an error response could be formatted:<em> </em></p>
<pre>HTTP/1.1 200 OK
Date: Tue, 01 Jul 2008 15:22:00 GMT
Content-Length: <span id="lblLength">384 </span>
Content-Type: text/xml
Connection: close

&lt;?xml version="1.0"?&gt;
&lt;methodResponse&gt;
  &lt;fault&gt;
    &lt;value&gt;
      &lt;struct&gt;
        &lt;member&gt;
          &lt;name&gt;faultCode&lt;/name&gt;
          &lt;value&gt;&lt;int&gt;1&lt;/int&gt;&lt;/value&gt;
        &lt;/member&gt;
        &lt;member&gt;
          &lt;name&gt;faultString&lt;/name&gt;
          &lt;value&gt;&lt;string&gt;Invalid request.&lt;/string&gt;&lt;/value&gt;
        &lt;/member&gt;
      &lt;/struct&gt;
    &lt;/value&gt;
  &lt;/fault&gt;
&lt;/methodResponse&gt;</pre>
<p><em>Note: there is no official specification for error codes and error messages. Each API designer should conscientiously create error codes and error messages for each possible scenario. Still, I could find one attempt to make error codes more official on <a href="http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php">this webpage</a>.</em></p>
<p>This is typical of a XML-RPC protocol: instead of relying on an existing standard, XML-RPC adds a new abstraction layer. A <a href="http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/">RESTful approach</a> would have used the HTTP status tool (namely: a <code>HTTP/1.1 400 Bad Request</code>) to notify the client that the request didn&#8217;t work; instead, the XML-RPC approach clearly overwrites HTTP and puts the error message in the very XML response delivered. As a matter of fact, the HTTP status of the response is still <code>HTTP/1.1 200 OK</code> even though the request resulted in a failure.</p>
<p>The three examples above illustrate how XML-RPC looks like both in terms of requests and responses. The underlying structure is easy to guess: a <strong>request</strong> has to be contained between <code>&lt;methodCall&gt;</code> tags and specify both the <code>&lt;methodName&gt;</code> and optional <code>&lt;params&gt;</code> (parameters). Symmetrically, a response must be contained between <code>&lt;methodResponse&gt;</code> tags and speficy optional <code>&lt;params&gt;</code>. Parameters are contained in-between <code>&lt;params&gt;</code> tags and each parameter must be surrounded by <code>&lt;param&gt;</code> and <code>&lt;value&gt;</code> tags, and then tags corresponding to their <strong>data type</strong>. For example, an integer parameter will be sent like this: <code>&lt;param&gt;&lt;value&gt;&lt;int&gt;23&lt;/int&gt;&lt;/value&gt;&lt;/param&gt;</code>.</p>
<p>XML-RPC defines several types of vanilla data types:</p>
<ul>
<li><code>int</code> or <code>i4</code>: 32-bit integers (e.g. <code>&lt;int&gt;23&lt;/int&gt;</code> or <code>&lt;i4&gt;23&lt;/i4&gt;</code>)</li>
<li><code>double</code>: 64-bit floating-point numbers (e.g. <code>&lt;double&gt;2.7812&lt;/double&gt;</code>)</li>
<li><code>boolean</code>: boolean (true (1) or false (0): e.g. <code>&lt;boolean&gt;1&lt;/boolean&gt;</code>)</li>
<li><code>string</code>: ASCII or Unicode text (e.g. <code>&lt;string&gt;Hello World!&lt;/string&gt;</code>)</li>
<li><code>dateTime.iso8601</code>: a datetime (e.g. <code>&lt;dateTime.iso8601&gt;20080701T15:22:00&lt;/dateTime.iso8601&gt;</code>)</li>
<li><code>base64</code>: some base64-encoded information (e.g. <code>&lt;base64&gt;SGVsbG8gV29ybGQh&lt;/base64&gt;</code>)</li>
</ul>
<p>And two types of elaborated data types:</p>
<ul>
<li><code>array</code>: as shown in the &#8220;sample successful response&#8221; above, arrays further enclose data in &lt;data&gt; tags with as many &lt;value&gt; sub-items as there are values in the array (together with their data types)</li>
<li><code>struct</code>: as shown  in the &#8220;sample failure response&#8221; above, structured data is made of &lt;members&gt;, each of them having a &lt;name&gt; and a &lt;value&gt; with a specific data type (a bit like an associative array in PHP)</li>
</ul>
<p><em>Note: both <strong>struct</strong> and <strong>array</strong> elements are recursive (I.e. a struct element can contain an array containing struct elements etc.): this opens endless possibilities for data formatting.</em></p>
<p>Programmatically speaking, creating XML-RPC clients and servers using PHP and relying on <a href="http://php.net/curl">cURL</a> and <a href="http://php.net/simplexml">SimpleXML</a> is absolutely not more complicated than the numerous code snippets explained in parts <a href="http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/">1</a>, <a href="http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/">2</a> and <a href="http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/">3</a>. Only the <strong>XML syntax</strong> changes. Also note that there is a specific PHP extension for using XML-RPC (more information on <a href="http://php.net/xmlrpc">php.net</a>).</p>
<p><a href="http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/">The pursuit of APIness</a> continues next week with a quick review of XML-RPC&#8217;s successor: <strong>SOAP</strong>.</p>
<p><em>(go to <a href="http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/">Part 5: SOAP: Hot or not?</a>)</em></p>


<p>Related posts:<ol><li><a href='http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 2)'>The pursuit of APIness (part 2)</a> <small>Last week we looked at web forms and we observed...</small></li><li><a href='http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 3)'>The pursuit of APIness (part 3)</a> <small>In part 2, we saw how could be designed an...</small></li><li><a href='http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 5)'>The pursuit of APIness (part 5)</a> <small>XML-RPC is damn easy to use and many projects still...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The pursuit of APIness (part 3)</title>
		<link>http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/</link>
		<comments>http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 10:36:58 +0000</pubDate>
		<dc:creator>nemetral</dc:creator>
		
		<category><![CDATA[Webdev]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[http]]></category>

		<category><![CDATA[rest]]></category>

		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://nemetral.net/?p=44</guid>
		<description><![CDATA[In part 2, we saw how could be designed an XML-based API structure for fictitious website community.com allowing 3rd party developers to get access to members of a given age and living in a given city. The problem was: is it really a good idea to let every website or webapp design its own fancy API? It is now time to introduce the 3 main standard API structures: REST, XML-RPC and SOAP.


Related posts:<ol><li><a href='http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 2)'>The pursuit of APIness (part 2)</a> <small>Last week we looked at web forms and we observed...</small></li><li><a href='http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 1)'>The pursuit of APIness (part 1)</a> <small>Say you need to upload a set of 100 pictures...</small></li><li><a href='http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 4)'>The pursuit of APIness (part 4)</a> <small>Last week we reviewed the principles behind a RESTful architecture....</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/">part 2</a>, we saw how could be designed an XML-based API structure for fictitious website community.com allowing 3rd party developers to get access to members of a given age and living in a given city. The problem was: is it really a good idea to let every website or webapp design its own fancy API? It is now time to introduce the 3 main standard API structures: <strong>REST</strong>, <strong>XML-RPC</strong> and <strong>SOAP</strong>.<span id="more-44"></span></p>
<h2>Part 3: Let&#8217;s take a REST</h2>
<p><strong>REST</strong> (REpresentational State Transfer) is actually more than a plain API structure. When coining this concept, <a href="http://en.wikipedia.org/wiki/Roy_Fielding">Roy Fielding</a> <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm">described</a> an entire <strong>style of software architecture</strong> based on:</p>
<ul>
<li><strong>protocol constraints</strong>:  the protocol has to be client-server, stateless, cacheable, layered and allowing code-on-demand</li>
<li><strong>resources</strong>: resources are fundamental informational elements on which operations can be realized (representing, linking, modifying, including, searching, caching etc.)</li>
<li><strong>universal syntax</strong>:<strong> </strong>resources are uniquely addressable using a universal syntax</li>
<li><strong>representation</strong>: resources are not data and therefore need to be represented (through pictures, HTML or content of any kind)</li>
<li><strong>uniform interface</strong>: the transfer of state is executed through well-defined operations and content-types</li>
</ul>
<p>An <em>good example</em> of RESTful architecture is the World Wide Web: <strong>HTTP</strong> is client-server, cacheable, layered, stateless <em>when used RESTfully</em> (i.e. without cookies or sessions), able to carry code-on-demand (e.g. JavaScript or Java applets) and accesses resources through a uniform interface (HTTP methods such as GET/POST/PUT/DELETE, MIME content-types, headers and URIs). Still, <strong>HTTP can be used more or less RESTfully</strong> and we can imagine <strong>other RESTful architectures</strong> than HTTP.</p>
<p>Let&#8217;s now apply the REST principles to the code snippets we have written in <a href="http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/">part 2</a>. A RESTful API doesn&#8217;t have to comply with a given XML format but with an architectural style. So here is how we could rewrite our API call in a RESTful manner, i.e. using the full potential or URIs and HTTP methods:</p>
<pre>GET /members?age=23&amp;city=Indianapolis HTTP/1.1
Host: api.community.com</pre>
<p><em>As you can see, the URL has changed: we are no longer POSTing XML to an opaque &#8220;submit&#8221; resource but rather calling a meaningful </em><em>&#8220;members&#8221; r</em><em>esource using the <strong>GET</strong> HTTP method and specifying meaningful parameters directly in the URL.<br />
</em></p>
<pre>HTTP/1.1 200 OK
Date: Tue, 17 Jun 2008 20:24:00 GMT
Content-Length: 85
Content-Type: application/text-xml

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;data&gt;
    &lt;name&gt;Anna&lt;/name&gt;
    &lt;name&gt;Lisa&lt;/name&gt;
  &lt;/data&gt;</pre>
<p><em>The response format does not need to change: as we&#8217;ve seen, REST doesn&#8217;t define a XML format but gives general principles of architectural design. </em></p>
<p>Programmatically speaking, there is little change in the script consuming the web service (we&#8217;re still using PHP, <a href="http://php.net/curl">cURL</a> and <a href="http://php.net/simplexml">SimpleXML</a>). This is what our code would look like:</p>
<pre>&lt;?php

  // STEP 1: SEND THE REQUEST
  $url = 'http://api.community.com/members?age=23&amp;city=Indianapolis';
  $handle = curl_init();
  curl_setopt($handle, CURLOPT_URL, $url);
  curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
  $response = curl_exec($handle);
  curl_close($handle);

  // STEP 2: PARSE THE RESULT AND DISPLAY THE NAMES
  if ($response) {
    $result = new SimpleXMLElement($response);
    $val = array();
    foreach ($result-&gt;name as $name) {
      $val[] = (string) $name;
    }
    print_r($values);
  } else {
      echo "An error occurred.";
  }

?&gt;</pre>
<p><em>Note: in case the parameters you provide to the URL have special caracters you need to <code>urlencode()</code> them. Also, note that we have added a condition to check the response before looping through it.<br />
</em></p>
<p>Let&#8217;s now have a look at the script providing the web service; here is an example of how the REST call could be handled (assuming the script name is <code>members.php</code>, located in <code>/scripts</code> and accessible through Apache URL rewriting):</p>
<pre>RewriteEngine on
RewriteRule ^members(.*)$ scripts/members.php$1</pre>
<p>And now the script:</p>
<pre>&lt;?php

  $connection = mysql_connect('host', 'user', 'password');
  mysql_select_db('database', $connection);

  $age = $_GET['age'];
  $city = $_GET['city'];
  if (!is_int($age) || !is_string($city)) {
    header('HTTP/1.1 400 Bad Request');
    exit();
  } else {
    $query = 'SELECT name FROM members WHERE age=' . $age .
             ' AND city=' . $city;
    $data = mysql_query($query);
    $members = array();
    header('Content-Type: application/text-xml');
    echo "&lt;data&gt;";
    while ($item = mysql_fetch_array($data)) {
      echo "&lt;name&gt;" . $item['name'] . &lt;/name&gt;;
    }
    echo "&lt;/data&gt;";
  }

?&gt;</pre>
<p>In a nutshell, here is why this rewritten script is more RESTful:</p>
<ul>
<li>we consume the web service through a <strong>GET</strong> parameter calling a meaningful <strong>members</strong> resources and specifying meaningful <strong>parameters</strong> right in the request URI</li>
<li>in case there is an error (e.g. incorrect data for the <strong>age</strong> parameter), we use a dedicated HTTP status to carry the error message instead of adding a layer of XML in the response</li>
</ul>
<p>The most important thing to remember about <strong>REST</strong> is that it&#8217;s only a set of architectural recommandations. Next week we&#8217;ll have a look at another API standard focusing on the XML message format more than the general architecture: <strong>XML-RPC</strong>.</p>
<p><em>(go to <a href="http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/">Part 4: Review of XML-RPC</a>)</em></p>


<p>Related posts:<ol><li><a href='http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 2)'>The pursuit of APIness (part 2)</a> <small>Last week we looked at web forms and we observed...</small></li><li><a href='http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 1)'>The pursuit of APIness (part 1)</a> <small>Say you need to upload a set of 100 pictures...</small></li><li><a href='http://nemetral.net/2008/07/01/the-pursuit-of-apiness-part-4/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 4)'>The pursuit of APIness (part 4)</a> <small>Last week we reviewed the principles behind a RESTful architecture....</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The pursuit of APIness (part 2)</title>
		<link>http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/</link>
		<comments>http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 16:42:59 +0000</pubDate>
		<dc:creator>nemetral</dc:creator>
		
		<category><![CDATA[Webdev]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[http]]></category>

		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://nemetral.net/?p=40</guid>
		<description><![CDATA[Last week we looked at web forms and we observed what was happening under the hood in terms of requests and data transferred; as an example, we tried to emulate a specific web form through a PHP script which sent a request to the web server and parsed the result to extract relevant information. The conclusion was: it's possible, but it's not clean. This week we'll see how transparent automation can be. 


Related posts:<ol><li><a href='http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 3)'>The pursuit of APIness (part 3)</a> <small>In part 2, we saw how could be designed an...</small></li><li><a href='http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 1)'>The pursuit of APIness (part 1)</a> <small>Say you need to upload a set of 100 pictures...</small></li><li><a href='http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 5)'>The pursuit of APIness (part 5)</a> <small>XML-RPC is damn easy to use and many projects still...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/">Last week</a> we looked at web forms and we observed what was happening under the hood in terms of requests and data transferred; as an example, we tried to emulate a specific web form through a PHP script which sent a request to the web server and parsed the result to extract relevant information. The conclusion was: <strong>it&#8217;s possible, but it&#8217;s not clean</strong>. This week we&#8217;ll see how transparent automation can be. <span id="more-40"></span></p>
<h2>Part 2: XML rocks</h2>
<p>An <strong>Application Programming Interface</strong> is a predefined set of procedures for a program to use another one. On the Internet, an API will make it possible for a <strong>computer</strong> to use another one. Contrary to the hackers&#8217; method previously explained, web APIs are meant to be officially supported by the webapp owners through extensive documentation and support. Your script will no longer try to imitate the human&#8217;s way with variables names and action URL but will rather take <strong>his own path to get data from the server</strong>.</p>
<p>Web APIs mostly rely on <strong>XML</strong>, which makes it possible to transfer structured data over the web. Basically, instead of sending raw POST variables to the server and receiving HTML, your request will send and receive <strong>clean and unchanging</strong> XML data.</p>
<p>At first, there is no limit to imagining and designing an API. Based on the example in <a href="http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1">part 1</a>, we could imagine the following kind of request and response:</p>
<pre>POST /submit HTTP/1.1
Host: api.community.com
Content-Length: 105
Content-Type: application/text-xml

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;data&gt;
    &lt;name&gt;Joe&lt;/name&gt;
    &lt;city&gt;Indianapolis&lt;/city&gt;
    &lt;age&gt;23&lt;/age&gt;
  &lt;/data&gt;</pre>
<p><em>Note: it is quite common to design the API so that requests are sent to a subdomain like api.community.com instead of www.community.com. This way, requests at subdomain <strong>www</strong> are supposed to be sent by human beings and trigger HTML responses whereas requests at subdomain <strong>api </strong>are supposed to be sent by computers and trigger XML responses. Also note that I removed the <strong>.php</strong> extension from the <strong>submit</strong> page: through the API, we&#8217;re not really accessing a <strong>page</strong> but rather a <strong>resource</strong>.<br />
</em></p>
<pre>HTTP/1.1 200 OK
Date: Tue, 17 Jun 2008 20:24:00 GMT
Content-Length: 85
Content-Type: application/text-xml

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;data&gt;
    &lt;name&gt;Anna&lt;/name&gt;
    &lt;name&gt;Lisa&lt;/name&gt;
  &lt;/data&gt;</pre>
<p>Programmatically speaking, coding the request in PHP is possible using <a href="http://php.net/curl">cURL</a> and parsing the response would certainly be easier using <a href="http://php.net/simplexml">SimpleXML</a> (included in PHP5). Therefore, implementing the above API call in PHP would look like this:</p>
<pre>&lt;?php

   // STEP 1: SEND THE REQUEST
   $url = 'http://api.community.com/submit';
   $header = array('Content-type: application/text-xml');
   $xml = '&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;data&gt;&lt;name&gt;Joe&lt;/name&gt;
           &lt;city&gt;Indianapolis&lt;/city&gt;&lt;age&gt;23&lt;/age&lt;/data&gt;';
   $handle = curl_init();
   curl_setopt($handle, CURLOPT_URL, $url);
   curl_setopt($handle, CURLOPT_HTTPHEADER, $header);
   curl_setopt($handle, CURLOPT_POSTFIELDS, $xml);
   curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
   $response = curl_exec($handle);
   curl_close($handle);

   // STEP 2: PARSE THE RESULT AND DISPLAY THE NAMES
   $result = new SimpleXMLElement($response);
   $val = array();
   foreach ($result-&gt;name as $name) {
      $val[] = (string) $name;
   }
   print_r($values);

?&gt;</pre>
<p><em>Note: in this cURL script I had to specify the <strong>Content-type</strong> header so that our request could be correctly interpreted by the server. I could have used a few more options such as CURLOPT_TIMEOUT for example.<br />
</em></p>
<p>Using an API is better than forcing a web form for 3 reasons:</p>
<ul>
<li>the request goes through a special path designed for computers which is clearly defined at subdomain api.community.com</li>
<li>the response data is better structured and easier to parse than a raw HTML page</li>
<li>XML responses being provided for machines, the developers at community.com must commit on keeping a <strong>constant XML format</strong>: this means, for example, that they can&#8217;t suddenly stop accepting &lt;city&gt; tags  in the requests or change &lt;name&gt; tags for &lt;person&gt; tags in the responses (otherwise it would spread a terrible mess in 3rd party applications leveraging their API)</li>
</ul>
<p>The last reason is well summed up in Google&#8217;s Joshua Bloch&#8217;s <a href="http://www.slideshare.net/guestbe92f4/how-to-design-a-good-a-p-i-and-why-it-matters-g-o-o-g-l-e/">famous keynote</a> on API design:</p>
<blockquote><p>Public APIs are forever - one chance to get it right.</p></blockquote>
<p>In the example above, we have assumed that community.com developers had created their API from scratch, inventing a custom XML structure for requests and responses. When it comes to designing the API, the reality is that developers tend to respect some <strong>existing API structures </strong>specifically designed for APIs in order to make their API easier to learn and use for 3rd party developers.</p>
<p>Today, 3 API standards are widely used on the web:</p>
<ul>
<li><strong>REST</strong> (REpresentational State Transfer)</li>
<li><strong>XML-RPC </strong>(XML Remote Procedure Call)</li>
<li><strong>SOAP</strong> (Simple Object Access Protocol)</li>
</ul>
<p>Next week we&#8217;ll have a look at these three XML standards with detailed examples of how to send and receive data.</p>
<p><em>(go to <a href="http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/">Part 3: Let&#8217;s take a REST</a>)</em></p>


<p>Related posts:<ol><li><a href='http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 3)'>The pursuit of APIness (part 3)</a> <small>In part 2, we saw how could be designed an...</small></li><li><a href='http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 1)'>The pursuit of APIness (part 1)</a> <small>Say you need to upload a set of 100 pictures...</small></li><li><a href='http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 5)'>The pursuit of APIness (part 5)</a> <small>XML-RPC is damn easy to use and many projects still...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The pursuit of APIness (part 1)</title>
		<link>http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/</link>
		<comments>http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 20:15:38 +0000</pubDate>
		<dc:creator>nemetral</dc:creator>
		
		<category><![CDATA[Webdev]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[http]]></category>

		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://nemetral.net/?p=34</guid>
		<description><![CDATA[Say you need to upload a set of 100 pictures on Flickr everyday. Not so difficult: you login to your Flickr account and start to manually upload the pictures. After a few days though, you start to feel a bit weird about having to spend all this time to manually upload files at an era where computers, after all, are supposed to replace us for repetitive tasks. Say your daily sets of 100 files are prepared in advance: wouldn't it be great if your computer could upload them to Flickr on its own?


Related posts:<ol><li><a href='http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 2)'>The pursuit of APIness (part 2)</a> <small>Last week we looked at web forms and we observed...</small></li><li><a href='http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 3)'>The pursuit of APIness (part 3)</a> <small>In part 2, we saw how could be designed an...</small></li><li><a href='http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 5)'>The pursuit of APIness (part 5)</a> <small>XML-RPC is damn easy to use and many projects still...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Say you need to upload a set of 100 pictures on <a href="http://flickr.com">Flickr</a> everyday. Not so difficult: you login to your Flickr account and start to manually upload the pictures. After a few days though, you start to feel a bit weird about having to spend all this time to manually upload files at an era where computers, after all, are supposed to replace us for repetitive tasks.  Say your daily sets of 100 files are prepared in advance: wouldn&#8217;t it be great if your computer could upload them to Flickr on its own?<span id="more-34"></span></p>
<h2>Part 1: The dirty way</h2>
<p>First thing that pops up in your mind is: let&#8217;s make my computer fill the forms alone! The idea is pretty straightforward: you write a script able to login to your Flickr account using your credentials and, once there, to fill the form fields. To fill the form fields? Does it mean I will see my computer in action and the cursor moving from one field to another one, opening the file selection dialog box, double clicking on one file, moving on to the next field etc.? Well, not really, for all this is pure client-side stuff.</p>
<p>In a form, only three things matter: the <strong>method</strong> (usually GET or POST), the <strong>names of the fields</strong> and the <strong>action URL</strong> (i.e. the URL your browser sends a request to when you press the &#8220;submit&#8221; button). At the end of the day, &#8220;automatically filling out a form&#8221; simply means sending a GET or POST request to the action URL with correct field names and values.</p>
<p>Let&#8217;s move on to a simple case study. When filling out a GET form on cool website http://www.community.com (fictitious example), here is what 23 years old Joe from Indianapolis would send back to the server:</p>
<pre>GET /submit.php?name=joe&amp;city=indianapolis&amp;age=23 HTTP/1.1
Host: www.community.com</pre>
<p>In case the form was a POST, here is what Joe would have sent back:</p>
<pre>POST /submit.php HTTP/1.1
Host: www.community.com
Content-Length: 33
Content-Type: application/x-www-form-urlencoded

name=joe&amp;city=indianapolis&amp;age=23</pre>
<p><em>Note: </em><em>the requests above are simplified ones, containing only the required headers for GET and POST methods. In fact, many more headers would usually be sent along with these ones (see the list of HTTP headers on <a href="http://en.wikipedia.org/wiki/List_of_HTTP_headers">Wikipedia</a>).</em></p>
<p>That was great. Now the funny thing is: upon receiving the request, the servers looks up the database to find other people aged 23 living in Indianapolis and sends a webpage back to Joe with the list of names on it. After Joe submitted his personal information, he will see a webpage featuring members Anna and Lisa.</p>
<pre>HTTP/1.1 200 OK
Date: Tue, 10 Jun 2008 19:38:07 GMT
Content-Length: 268
Content-Type: text/html

&lt;html&gt;
   &lt;head&gt;
      &lt;title&gt;Community.com rocks!&lt;/title&gt;
   &lt;/head&gt;
   &lt;body&gt;
      &lt;h1&gt;There are 2 members aged 23 and living in your town:&lt;/h1&gt;
      &lt;ul&gt;
         &lt;li&gt;Member #1: Anna&lt;/li&gt;
         &lt;li&gt;Member #2: Lisa&lt;/li&gt;
      &lt;/ul&gt;
   &lt;/body&gt;
&lt;/html&gt;</pre>
<p><em>Note: </em><em>the webpage above is a simplified one. Come on there&#8217;s not even a DOCTYPE declaration in it <img src='http://nemetral.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> !</em></p>
<p>That was so cool. By filling out a plain form, Joe was able to know some of his neighbours also belonging to http://www.community.com. Rephrased version: <strong>by sending out a request, Joe received a reply with data in it</strong>. A human (supposedly non geek) would read the data as displayed on his browser; but a script could parse the HTML and extract relevant bits of information.</p>
<p>Now Joe is a clever guy knowing about computers so he decides to write a script exploiting this form and aimed at retrieving the members from http://www.community.com aged 23 and living in Indianapolis. The script would essentially consist in emulating the web form by sending a request to http://www.community.com and then parsing the HTML result. Such a script could easily be used to know when new users of the same age and living in the same town become members of http://www.community.com: to do so, Joe would have to run it daily or make it a daily <a href="http://en.wikipedia.org/wiki/Cron">CRON</a> task.</p>
<p>Joe knows PHP and will use a wrapper called <a href="http://php.net/curl">cURL</a> to write the requests and then a regex to parse the results. Here is what the script could look like:</p>
<pre>&lt;?php

   // STEP 1: SEND THE POST REQUEST
   $url = 'http://www.community.com/submit.php';
   $handle = curl_init();
   curl_setopt($handle, CURLOPT_URL, $url);
   curl_setopt($handle, CURLOPT_POST, 1);
   curl_setopt($handle, CURLOPT_POSTFIELDS,
               'name=joe&amp;city=indianapolis&amp;age=23');
   curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
   $result = curl_exec($handle);
   curl_close($handle);

   // STEP 2: PARSE THE RESULT AND DISPLAY THE NAMES
   preg_match_all("|&lt;li&gt;Member #[0-9]+: (.*)&lt;/li&gt;|", $result, $match);
   print_r($match);

?&gt;</pre>
<p><em>Note: it is safer to use more options when writing a cURL request (especially options like CURLOPT_TIMEOUT).</em></p>
<p>In this script, Joe decided to simply print_r() the array of names, but he could have decided as well to insert them in a database or send them by email. The important thing is: <strong>Joe was able to get structured data out of a request using variables</strong>.</p>
<p>The next step would be to extend this script to all ages and cities in the US. Using two nested loops featuring all ages between 21 and 100 and all main cities of the US for example, it would be possible to <strong>rebuild a fair part of http://www.community.com&#8217;s members database</strong>.</p>
<p>As a matter of fact, the script Joe is writing goes well beyond the normal use of the initial form and is certainly <strong>not supported</strong> by the website owners. Providing that they no longer want such scripts to automatically exploit the form and spit members&#8217; names, the developers at http://www.community.com have several weapons at their disposal:</p>
<ol>
<li> first thing they can do is to regularly change the names of the form fields, which means that Joe would have to update his own script each time there&#8217;s a such a change otherwise the script would blindly keep on sending outdated variables to the server</li>
<li>second thing they can do is to regularly update the HTML code of the delivered webpage: for example, adding a simple class to the lines would break the regex</li>
<li>third move: limiting the number of requests in a given timeframe, i.e. making it impossible for a single IP to send more than one request every 10 minutes for example</li>
<li>lethal weapon: adding a <a href="http://en.wikipedia.org/wiki/Captcha">captcha</a>, which is a much trickier obstacle to skip</li>
</ol>
<p>The script Joe has written is a hacker&#8217;s self-made <strong>API</strong> of http://www.community.com&#8217;s members database: <strong>it&#8217;s a bridge towards the content stored in there</strong>. Now wouldn&#8217;t it be nicer if, instead of sniffing variable names and updating a regex, it could be possible to send a structured query to http://www.community.com and get a structured, officially supported and <strong>constant</strong> response?</p>
<p><em>(go to <a href="http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/">part 2 : XML rocks</a>)</em></p>


<p>Related posts:<ol><li><a href='http://nemetral.net/2008/06/17/the-pursuit-of-apiness-part-2/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 2)'>The pursuit of APIness (part 2)</a> <small>Last week we looked at web forms and we observed...</small></li><li><a href='http://nemetral.net/2008/06/25/the-pursuit-of-apiness-part-3/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 3)'>The pursuit of APIness (part 3)</a> <small>In part 2, we saw how could be designed an...</small></li><li><a href='http://nemetral.net/2008/07/11/the-pursuit-of-apiness-part-5/' rel='bookmark' title='Permanent Link: The pursuit of APIness (part 5)'>The pursuit of APIness (part 5)</a> <small>XML-RPC is damn easy to use and many projects still...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://nemetral.net/2008/06/10/the-pursuit-of-apiness-part-1/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
