<?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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Think Vitamin &#187; APIs</title>
	<atom:link href="http://thinkvitamin.com/category/dev/api-dev/feed/" rel="self" type="application/rss+xml" />
	<link>http://thinkvitamin.com</link>
	<description>A blog about the web</description>
	<lastBuildDate>Thu, 09 Sep 2010 01:38:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>How to Get Started with the Twitter API</title>
		<link>http://thinkvitamin.com/dev/how-to-get-started-with-the-twitter-api/</link>
		<comments>http://thinkvitamin.com/dev/how-to-get-started-with-the-twitter-api/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 06:52:58 +0000</pubDate>
		<dc:creator>Kari Pätilä</dc:creator>
				<category><![CDATA[APIs]]></category>
		<category><![CDATA[Dev]]></category>
		<category><![CDATA[Learn]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=2980</guid>
		<description><![CDATA[By <strong>Kari Pätilä</strong><br />Thanks to some very nice open source libraries for quite a few programming languages, interacting with the Twitter API has become exceedingly simple. In this article we&#8217;ll be looking at different ways to pull in data from Twitter. The libraries page of Twitter&#8217;s API wiki is a good place to start. For these examples I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthinkvitamin.com%2Fdev%2Fhow-to-get-started-with-the-twitter-api%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthinkvitamin.com%2Fdev%2Fhow-to-get-started-with-the-twitter-api%2F&amp;source=thinkvitamin&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://events.carsonified.com/fowa/2009/london/schedule?utm_source=TV&amp;utm_medium=banner&amp;utm_campaign=Kevin%2Band%20Gary%20Show"><img src="http://ryancarson.com/uploads/kevin_gary.png" alt="Kevin and Gary show at FOWA London" /></a></p>
<p>Thanks to some very nice open source libraries for quite a few programming languages, interacting with the Twitter API has become exceedingly simple. In this article we&#8217;ll be looking at different ways to pull in data from Twitter.</p>
<p><span id="more-2980"></span></p>
<p>The <a href="http://apiwiki.twitter.com/Libraries">libraries page</a> of Twitter&#8217;s API wiki is a good place to start. For these examples I&#8217;m going to use the <a href="http://code.google.com/p/php-twitter/">php-twitter</a> class, but I&#8217;ll include the requests and responses so this doesn&#8217;t turn out to be all PHP. After all, the API itself doesn&#8217;t care which language I&#8217;m using.
</p>
<p>The php-twitter <a href="http://php-twitter.googlecode.com/files/php-twitter-1.1.zip">zip archive</a> contains some nested folders and finally a file: class.twitter.php. You&#8217;ll eventually get to it, so keep opening those folders!
</p>
<h3>Getting your timeline from Twitter</h3>
<p>With this library you don&#8217;t have to worry about data exchange formats (the default is JSON), but if you&#8217;re still stuck with PHP 4, you might have to set the $type variable to &#8216;xml&#8217;. But, let&#8217;s face it: if you enjoy XML you&#8217;re kind of insane, aren&#8217;t you? If your host is still using PHP 4, chances are that they&#8217;ll update you to the latest version if you ask them nicely.
</p>
<p>The API method we&#8217;ll be using is <a href="http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses-user_timeline">user_timeline</a>. You can check out the output by pointing your browser to <a href="http://twitter.com/statuses/user_timeline/karipatila.xml">http://twitter.com/statuses/user_timeline/karipatila.xml</a>. Notice the &#8220;.xml&#8221; &mdash; that&#8217;s the data exchange format. You can use &#8220;json&#8221;, &#8220;rss&#8221; or &#8220;atom&#8221; there as well. That URL is the GET request the API is responding to, which could be made using any programming language.
</p>
<p>So, using the library, this is all we need to fetch my timeline:</p>
<pre><code>&lt;?php
header('Content-type: text/html; charset=utf-8');
require_once 'class.twitter.php';
$t = new twitter;
$data = $t->userTimeline('karipatila');
?&gt;</code></pre>
<p>First we make sure the script can handle unicode characters and then we include class.twitter.php. Next we&#8217;ll set up a new instance of the php-twitter class, which can be used to pull in some data.</p>
<p>The script loads the timeline from Twitter and stores it into the $data variable. Along with some user information it contains the tweets themselves, which are what we&#8217;re really interested in. Let&#8217;s take a look at what kind of information we&#8217;re getting. This is one of my tweets in the $data array:
</p>
<pre><code><strong>[truncated] => </strong>
<strong>[text] => </strong>TomTom Nordic, 69,90&euro;: http://bit.ly/wX51t (App Store link) - wonder how expensive the car kit is?

<strong>[in_reply_to_status_id] => </strong>
<strong>[created_at] => </strong>Mon Aug 17 07:55:51 +0000 2009
<strong>[favorited] => </strong>
<strong>[in_reply_to_user_id] => </strong>
<strong>[id] => </strong>3358348095

<strong>[in_reply_to_screen_name] => </strong>
<strong>[source] => </strong>&lt;a href="http://www.atebits.com/" rel="nofollow"&gt;Tweetie&lt;/a&gt;</code></pre>
<p>We can use that information to make a script that lists my recent tweets. The API method <em>statuses user_timeline</em> returns the 20 most recent statuses posted from the authenticating user. I also wanted to link back to the accounts that are being replied to, so I&#8217;m looking for an @ symbol followed by one or more word characters and linking them to their respective Twitter profiles:
</p>
<pre><code>&lt;ul&gt;
	&lt;?php foreach($data as $d){ ?&gt;
	&lt;li&gt;&lt;?php echo preg_replace('/(^|\s)@(\w+)/','\1&lt;a href="http://twitter.com/\2"&gt;@\2&lt;/a&gt;', $d-&gt;text); ?&gt;&lt;/li&gt;

	&lt;?php } ?&gt;
&lt;/ul&gt;</code></pre>
<p>A short note on <a href="http://apiwiki.twitter.com/Rate-limiting">rate limitations</a>; caching the output from this script will become necessary sooner or later. The technical details are beyond the scope of this article, but you might want to consider saving the output into a database or a file and checking for updates every couple of minutes or so. A limit of 150 requests per hour applies to the REST API.</p>
<p>Get the source for fetching a user&#8217;s timeline <a href="http://ryancarson.com/uploads/user_timeline.php.txt">here</a>.</p>
<h3>Let&#8217;s look for treasure</h3>
<p>For example, let&#8217;s do a search for the hashtag &#8220;#carsonified&#8221;. They have recently announced <a href="http://hello.carsonified.com/">Hello App</a>, so there should be some chatter around that subject. We can add terms to the search like this:</p>
<p><code>$data = $s->search('#carsonified OR #HelloApp');</code></p>
<p>The search API method requires the query to be <a href="http://en.wikipedia.org/wiki/URL_encoding">URL encoded</a>, so we replace # with %23 in the request: <a href="http://search.twitter.com/search.json?q=%23carsonified&#038;rpp=5&#038;page=1">http://search.twitter.com/search.json?q=%23carsonified&#038;rpp=5&#038;page=1</a>. The search API accepts either &#8220;json&#8221; or &#8220;atom&#8221; as the exchange format.</p>
<p>If we break that request down, we find it contains the following information:</p>
<pre><code>q=[query string]
rpp=[results per page]
page=[page number]</code></pre>
<p>The search API has virtually no rate limits, so you don&#8217;t have to worry about your app getting throttled. Note that this time we&#8217;re also creating another instance with</p>
<p><code>$s = new summize;</code></p>
<p>which refers to the search class found in the php-twitter library.</p>
<pre><code>&lt;?php
header('Content-type: text/html; charset=utf-8');
require_once 'class.twitter.php';
$t = new twitter;

$s = new summize;
$data = $s->search('#carsonified');
$data = $data->results;
?&gt;</code></pre>
<p>In this example one tweet stored in $data might contain the following information:</p>
<pre><code><strong>[text] => </strong>Just trying out Matt by #carsonified. uniquely designed site with workable UI.
<strong>[to_user_id] => </strong>
<strong>[from_user] => </strong>_midnightshad
<strong>[id] => </strong>3284756132
<strong>[from_user_id] => </strong>2270963

<strong>[iso_language_code] => </strong>en
<strong>[source] => </strong>&lt;a href=&quot;http://themattinator.com&quot; rel=&quot;nofollow&quot;&gt;Matt&lt;/a&gt;
<strong>[profile_image_url] => </strong>http://a1.twimg.com/profile_images/60040548/panda_normal.jpg

<strong>[created_at] => </strong>Thu, 13 Aug 2009 11:50:01 +0000</code></pre>
<p>We can use this to make a simple listing based on the results:</p>
<pre><code>&lt;?php
header('Content-type: text/html; charset=utf-8');
require_once 'class.twitter.php';

$t = new twitter;
$s = new summize;
$data = $s->search('#carsonified');
$data = $data->results;
?&gt;
&lt;ul&gt;

&lt;?php foreach($data as $d){ ?&gt;
	&lt;li&gt;
		&lt;img src="&lt;?php echo $d-&gt;profile_image_url; ?&gt;" alt="" /&gt;
		&lt;?php echo preg_replace('/(^|\s)@(\w+)/','\1&lt;a href="http://twitter.com/\2"&gt;@\2&lt;/a&gt;', $d-&gt;text); ?&gt;

		&lt;em&gt;by&lt;/em&gt;
		&lt;a href="http://twitter.com/&lt;?php echo $d-&gt;from_user; ?&gt;"&gt;&lt;?php echo $d-&gt;from_user; ?&gt;&lt;/a&gt;
		&lt;?php echo $d-&gt;created_at; ?&gt; &lt;em&gt;from&lt;/em&gt; 

		&lt;?php echo html_entity_decode($d-&gt;source); ?&gt;
	&lt;/li&gt;
&lt;?php } ?&gt;
&lt;/ul&gt;</code></pre>
<p>This script outputs the tweets containing the word #carsonified along with profile images, timestamps and links to the client used.</p>
<p><img src="http://ryancarson.com/uploads/tweets.png" alt="Screenshot of We Love Typography's listing of tweets containing the hashtag #WLT" /><br />
	<a href="http://welovetypography.com/tweets/">We Love Typography</a> uses similar formatting to pull in tweets with the hashtag #WLT.</p>
<p>In the following source file I&#8217;m using a function for formatting the <em>created_at</em> field, so instead of &#8220;Fri, 14 Aug 2009 14:24:58 +0000&#8243; you will get something like &#8220;3 days, 17 hours ago&#8221;.
</p>
<p>Get the source for searching Twitter <a href="http://ryancarson.com/uploads/twitter_search.php.txt">here</a>. You&#8217;ll also need the <a href="http://ryancarson.com/uploads/time_passed.php.txt">file with the time_passed function</a> for this one.</p>
<h3>When the library just isn&#8217;t good enough</h3>
<p>The search API returns 50 results by default, which might not be convenient for everyone. The class php-twitter doesn&#8217;t set the results per page variable in the query strings, so let&#8217;s add that. You need to open the class.twitter.php file and replace line 844 with this:</p>
<p><code>function search( $terms=false, $rpp=false, $page=1, $callback=false )</code></p>
<p>Finally we add these three lines starting from line 854:</p>
<pre><code>if( $rpp )
$qs[] = 'rpp=' . $rpp;
$qs[] = 'page=' . $page;</code></pre>
<p>After these changes: </p>
<p><code>$data = $s->search('#carsonified', 5);</code></p>
<p>would only return the five latest results, and it would set the pagination to page one, whereas</p>
<p><code>$data = $s->search('#carsonified', 5, 2);</code></p>
<p>would set it to start from page two.</p>
<h3>Know your API</h3>
<p>The <a href="http://apiwiki.twitter.com/Twitter-API-Documentation">API Documentation</a> is pretty well done, so make sure to read it. Check out the methods like searching for current or daily trends or listing your followers and go make the next big Twitter app!</p>
<img src="http://thinkvitamin.com/?ak_action=api_record_view&id=2980&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://thinkvitamin.com/dev/how-to-get-started-with-the-twitter-api/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Go Forth and API</title>
		<link>http://thinkvitamin.com/web-apps/go-forth-and-api/</link>
		<comments>http://thinkvitamin.com/web-apps/go-forth-and-api/#comments</comments>
		<pubDate>Sun, 02 Jul 2006 07:55:41 +0000</pubDate>
		<dc:creator>Cameron Adams</dc:creator>
				<category><![CDATA[APIs]]></category>
		<category><![CDATA[Dev]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Web Apps]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.thinkvitamin.com/features/ajax/go-forth-and-api</guid>
		<description><![CDATA[By <strong>Cameron Adams</strong><br />To most, the virtues of Web 2.0 are rather ephemeral; that&#8217;s always been one of its main criticisms. However, I like to think that one of the movement&#8217;s key aspects is a sense of community, an ability to create sites and applications that bring people together. One of the most powerful ways to bring people [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthinkvitamin.com%2Fweb-apps%2Fgo-forth-and-api%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthinkvitamin.com%2Fweb-apps%2Fgo-forth-and-api%2F&amp;source=thinkvitamin&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>
To most, the virtues of Web 2.0 are rather ephemeral; that&#8217;s always been one of its main criticisms. However, I like to think that one of the movement&#8217;s key aspects is a sense of community, an ability to create sites and applications that bring people together.</p>
<p>
One of the most powerful ways to bring people together on the Web is to give them ownership of the sites that they frequent &#8211; make them active participants in the development and growth of the product they&#8217;re using. There&#8217;s many different approaches you can take to implementing this idea, but I&#8217;m going to talk about just one of them: setting your data free.
</p>
<p>
Data sharing isn&#8217;t a new idea. It&#8217;s a concept as old as the Web, in fact, the Web is all about sharing data. However, most of the data available on the Web is designed to be consumed by humans, through a browser. It&#8217;s encapsulated by HTML pages, trapped inside Flash files, and disguised by design. There used to be a time where, if you wanted to get any real data from a site that wasn&#8217;t your own, your only recourse would be to grab the raw HTML and scrape through that tag soup for the gem that you were looking for. Fancy writing a 15-line regular expression to get the weather off Yahoo!?
</p>
<p>
	However, data providers are slowly realising that offering their data in much more flexible formats can only be an advantage to them &#8211; they get used by more applications, they get seen by more eyeballs, they get more exposure.
</p>
<p>
	RSS is a great example of this. Strip all the images, colour, layout, font styles and browser dependence from a Web page, and what do you have? A lightweight, versatile data format that can be easily interpreted by pretty much any software out there. Two years ago it was barely on the radar. Now your green grocer has an RSS feed that tells you when the latest shipment of fresh guava has arrived.
</p>
<p>
	RSS is good, but it&#8217;s still a bit restrictive for real application development &#8211; the content provider tells you exactly what you&#8217;re going to get, and when you&#8217;re going to get it. What if, instead of getting the last 10 blog posts from your favourite incendiary author, you could get their last 10 posts that were tagged with &#8220;free beer&#8221;; or you could get their last 10 posts that were tagged with &#8220;free beer&#8221; and were written in Melbourne?
</p>
<p>
	What if you could take their last 10 <em>mo</em>blog posts that were tagged with &#8220;free beer&#8221; and written in Melbourne, get the geolocation data of each post, plot the exact position of each free beer spot on a street map and show it in relation to your current location? That&#8217;s a good night out. And <acronym title="Application Program Interface">API</acronym>s can let you do it.
</p>
<p>
	<strong>A</strong>pplication <strong>P</strong>rogram <strong>I</strong>nterfaces are, broadly speaking, tools for building software applications. An operating system API might help you build applications with a consistent interface, but Web APIs are mostly about giving you access to data.
</p>
<p>
	Even Web APIs aren&#8217;t a new idea. Google&#8217;s search API has been available via SOAP since 2002, and there&#8217;s definitely older services than that. However, the recent growth in Web API availability has been fuelled by two recent developments. The first, which I&#8217;ve already mentioned, was a philosophical change in the way that data is handled. The second was the introduction of AJAX. Again, not a new idea, or even a new technology, but sometimes it&#8217;s all about timing.
</p>
<p>
	Some of the more interesting JavaScript-friendly Web APIs that are available at the moment are:
</p>
<ul>
<li>
		<a href="http://www.flickr.com/services/api/">Flickr (Photo sharing API)</a>
	</li>
<li>
		<a href="http://del.icio.us/help/api/">Del.icio.us (Social bookmarking API)</a>
	</li>
<li>
		<a href="http://www.google.com/apis/maps/">Google Maps (Mapping API)</a>
	</li>
<li>
		<a href="http://developer.yahoo.com/maps/">Yahoo! Maps (Mapping API)</a>
	</li>
<li>
		<a href="http://upcoming.org/services/api/">Upcoming (Event planning API)</a>
	</li>
<li>
		<a href="http://developer.yahoo.com/search/">Yahoo! Search (Search engine API)</a>
	</li>
<li>
		<a href="http://developer.ebay.com/common/api/">eBay (Online auction API)</a>
	</li>
<li>
		<a href="http://www.amazon.com/gp/browse.html/ref=sc_fe_l_1/002-5739132-9234422?_encoding=UTF8&#038;node=3435361&#038;no=3435361&#038;me=A36L942TSJ2AJA">Amazon (E-commerce API)</a>
	</li>
</ul>
<p>
	The mapping APIs have received the most attention to-date, mainly through mapping &#8220;mashups&#8221; such as <a href="http://www.chicagocrime.org/">chicagocrime.org</a>, or <a href="http://dartmaps.mackers.com/">dartmaps.mackers.com</a>. They&#8217;re also probably one of the least flexible, because you are constrained by the mapping interface that the provider gives you. When you include the Google Maps API on your page, you gain access to a number of JavaScript functions that allow you to move and zoom the map, or add your own data and visual components, but you aren&#8217;t able to manipulate any of the original data, beyond what the existing JavaScript methods allow you to do. This is perhaps just a constraint of maps themselves &#8211; how many different forms can mapping data take? A good tutorial on how to create an application with the Google Maps API is available at <a href="http://www.xml.com/pub/a/2005/08/10/google-maps.html">Hacking Maps with the Google Maps API</a>.
</p>
<p>
	Other forms of data, however, offer greater possibilities.<br />
These web applications use AJAX to query the various non-map APIs and create new and unique ways to interact with data:
</p>
<ul>
<li>
		<a href="http://www.johnvey.com/features/deliciousdirector/">Delicious Director</a> (Uses the del.icio.us API)
	</li>
<li>
		<a href="http://api.local.yahoo.com/eb/">Yahoo! local events browser</a> (Uses the Yahoo! search engine APIs)
	</li>
<li>
		<a href="http://www.themaninblue.com/experiment/FamiliarFaces/">FamiliarFaces</a> (Uses the upcoming.org API and the Yahoo! image search API)
	</li>
<li>
		<a href="http://www.mindsack.com/?page_id=45">Mindsack integrated searching</a> (Uses the Yahoo! web search API)
	</li>
</ul>
<p>
	We&#8217;ll be taking a look at the how they access those APIs, so you can get right in and make your own data-sharing application.
</p>
<h4>
	Accessing Web APIs with AJAX<br />
</h4>
<p>
	Most Web APIs are accessed via HTTP, so they&#8217;re always going to be available to server-side scripts, however, the nexus that AJAX enables between user interaction and data communication, as well as the ease with which it can be incorporated into webpages, means that the use of APIs by client-side scripts offers some of the most exciting possibilities for Web applications.
</p>
<p>
	The <a href="http://www.flickr.com/services/api/">API for Flickr</a> has a number of methods that are specified by passing particular CGI parameters to a base script. For instance, to get a list of the most recently uploaded photos to all of Flickr, you would access their script:
</p>
<p>
	<code><br />
		http://www.flickr.com/services/rest/?method=flickr.photos.getRecent&#038;api_key=XXXX<br />
	</code>
</p>
<p>
	The &#8220;method&#8221; specifies exactly which method from the API you want to execute, and &#8220;api_key&#8221; is a way for Flickr to track who&#8217;s using what from their API. If you want to see the data that this call returns, simply sign up for your own Flickr API key, insert it into the string above, paste that string into your browser location bar, and you&#8217;ll get a nicely formatted XML file in return. Something like:
</p>
<p>
	<code></p>
<pre><rsp stat="ok">
<photos page="1" pages="10" perpage="100" total="1000">
<photo id="169563197" owner="98319521@N00" secret="f4002ac03f" server="67" title="turkije021" ispublic="1" isfriend="0" isfamily="0"/>
<photo id="169563188" owner="17208601@N00" secret="fbf107bffb" server="56" title="PICT0221~1" ispublic="1" isfriend="0" isfamily="0"/>
	</photos>
</rsp></pre>
<p>	</code>
</p>
<p>
	The same process applies for an XMLHttpRequest via JavaScript &#8211; you specify the URL above to your XMLHttpRequest object, and the client browser will go off and fetch it. (For a more in-depth look at creating XMLHttpRequest connections, see  <a href="http://www.xml.com/pub/a/2005/08/19/ajax.html">Remote Scripting with AJAX</a>) Because you get XML in return, you&#8217;ll be able to use JavaScript&#8217;s in-built DOM functions to parse the data in much the same way as you do for HTML; navigating through elements, getting attributes, etc. However, as with any XMLHttpRequest, the data doesn&#8217;t necessarily have to be XML, so a Web API could send back a simple text string instead. In fact &#8211; as we&#8217;ll see later &#8211; that&#8217;s what JSON does.
</p>
<h4>
	XMLHttpRequest Proxies<br />
</h4>
<p>
	Even though it&#8217;s theoretically possible to request this data from Flickr using XMLHttpRequest on the client-side, there&#8217;s one problem: cross site scripting. Currently, most browsers will not allow you to get data from other sites using XMLHttpRequest. Due to security restrictions that prevent cross site scripting (<acronym title="Cross site scripting">XSS</acronym>), they will not let JavaScript access a URL that is outside of the domain that the current page is being served from. This even applies to sub-domains on the same site, for example www.example.com versus dev.example.com.
</p>
<p>
	This is not an intractable problem, though. There are a couple of ways you can get around it, but they all require the server on the current domain to act as a proxy for the external data. This works because server-side scripts generally have more privileges than client-side scripts, so they are able to access any address on the Internet. With a server-side proxy, we create a script that accesses a remote server, gets the data and relays it back to the browser, making it look like the data was sent from www.example.com, when in reality it came from www.upcoming.org, or some other website which we proxy data for.
</p>
<h5>
	Apache Proxy<br />
</h5>
<p>
	The easiest way to proxy data is to get your web server to do it for you. You can set up a proxy in Apache by making sure the <code>mod_proxy</code> extension is loaded and editing the <code>httpd.conf</code> file to include your new proxy:
</p>
<p>
	<code><br />
		ProxyPass    /proxy/flickr/    http://www.flickr.com/<br />
		ProxyPassReverse    /proxy/flickr/    http://www.flickr.com/<br />
	</code>
</p>
<p>
	The first line forwards any requests from your server to Flickr&#8217;s, the second line handles any redirections that the Flickr server might respond with.
</p>
<p>
	However, if you&#8217;re running a site off a shared server, you more than likely won&#8217;t be able to edit <code>httpd.conf</code>, so you can always use <code>mod_rewrite</code> to redirect requests by editing a <code>.htaccess</code> file. If I put this inside the <code>.htaccess</code> file for the directory <code>/proxy/flickr/</code>:
</p>
<p>
	<code><br />
		RewriteEngine on<br />
		RewriteRule ^(.*)$ http://www.flickr.com/$1 [P]<br />
	</code>
</p>
<p>
	Anytime I make a call to a path inside <code>http://www.example.com/proxy/flickr/</code>, it will pass on all extra URL information to <code>http://www.flickr.com/</code>. So, when I reference <code>http://www.example.com/proxy/flickr/services/rest/</code> it&#8217;s actually passing the request through to <code>http://www.flickr.com/services/rest/</code>. The <code>[P]</code> at the end of the RewriteRule means that the re-direction is passed through without informing the user&#8217;s browser that a change of URL has occurred.
</p>
<h5>
	Application Proxy<br />
</h5>
<p>
	The second method to proxy data is to create a script that will do it for you &#8211; receive request URLs, create a connection, get the data, and return it to the requester. The exact code that you use to do this will differ depending upon what language you&#8217;re using, but if you are running PHP with the Curl extension installed (for creating external connections), then you could use this as your proxy script:
</p>
<p>
	<code><br />
		$remoteServer = "http://www.flickr.com";<br />
		$path = $_GET[&#8221;path&#8221;];<br />
		$proxyTarget = $remoteServer.$path;</p>
<p>		$connection = curl_init($proxyTarget);<br />
		curl_setopt($connection, CURLOPT_HEADER, false);<br />
		curl_setopt($connection, CURLOPT_RETURNTRANSFER, true);<br />
		$data = curl_exec($connection);<br />
		curl_close($connection);</p>
<p>		header(&#8221;Content-Type: text/xml&#8221;);<br />
		echo $data;<br />
	</code>
</p>
<p>
	This script assumes that you are passing a CGI parameter called &#8220;path&#8221; that specifies what location you want to retrieve from the remote server. Note that we don&#8217;t directly pass on this parameter to the Curl connection, as we don&#8217;t want this script to become an open proxy. Instead, we specify the exact address that we are using the proxy for &#8211; www.flickr.com &#8211; and this will limit its potential for abuse. You&#8217;d call it from a browser using this URL:
</p>
<p>
	<code><br />
		http://www.example.com/proxy.php?path=/services/rest/<br />
	</code>
</p>
<p>
	If you&#8217;re sending that over an XMLHttpRequest connection, you should remember to URL endcode it using <code>escape()</code>, so that any special characters inside the path are passed along properly.
</p>
<p>
	When we initialise the Curl connection, we tell it that we don&#8217;t want it to pass on any header information, but we do want it to pass on the content of the request. Then, once the data has been received we write the appropriate header back to the client browser and also forward on the data which we retrieved from the remote server.
</p>
<p>
	The downside of proxies is that you&#8217;re double handling your data every time &#8211; a request has to come to the current domain server, which then passes it along to the actual remote data server. Then the data has to go back to the current domain server before it can be sent to the client browser. This extra traffic will always introduce some delay; the amount of which depends on the network architecture and speed of the highway at any given time, so you&#8217;ll have to ask whether that delay (however minimal it is) is acceptable to your service.
</p>
<h5>
	JSON<br />
</h5>
<p>
	Another way to avoid XSS issues with XMLHttpRequest is to not use it all. How do you do that? You use <acronym title="JavaScript Object Notation">JSON</acronym>.
</p>
<p>
	JSON (short for JavaScript Object Notation) is an alternative format to XML. It actually stores data as an object literal &#8211; a structure that is natively available in JavaScript. So if you receive a JSON string you can use the JavaScript evaluation function <code>eval()</code> and it will automatically create an object structure that corresponds to the data that you want to retrieve. Although object literals are native to JavaScript, they&#8217;re farly easy for other languages to parse. Indeed, at <a href="http://www.json.org/">json.org</a> there are links to JSON parsers for over 20 different programming languages.
</p>
<p>
	Using <code>eval()</code> on a text string that you receive from a 3rd party can be a little scary &#8211; it opens up all sorts of security holes that could be exploited in your code, so you really have to trust the data provider if you&#8217;re blindly using JSON. There&#8217;s some parsers available that have been written in JavaScript by Douglas Crockford &#8211; the creator of JSON &#8211; that will offer some protection against malicious code. These are also available at www.json.org.
</p>
<p>
	Douglas calls JSON the &#8220;fat free alternative to XML&#8221;, mainly because it&#8217;s less verbose and requires less parsing than XML, particularly if you&#8217;re using it from inside JavaScript. If we translated the XML we had from Flickr earlier into a JSON structure, it might look like this:
</p>
<p>
	<code></p>
<pre>{
	"rsp": {
		"stat": "ok",
		"photos": {
			"page": "1",
			"pages": "10",
			"perpage": "100",
			"total": "1000",
			"photo": [
				{
					"id": "169563197",
					"owner": "98319521@N00",
					"secret": "f4002ac03f",
					"server": "67",
					"title": "turkije021",
					"ispublic": "1",
					"isfriend": "0",
					"isfamily": "0"
				},
				{
					"id": "169563188",
					"owner": "17208601@N00",
					"secret": "fbf107bffb",
					"server": "56",
					"title": "PICT0221~1",
					"ispublic": "1",
					"isfriend": "0",
					"isfamily": "0"
				}
			]
		}
	}
}</pre>
<p>	</code>
</p>
<p>
	It&#8217;s entirely possible to use JSON via XMLHttpRequest &#8211; make a request to the server, receive a text string and evaluate it &#8211; but one of its real advantages is that you don&#8217;t need XMLHttpRequest in order to get it. Because JSON is a JavaScript string, if you specify a server-side script that returns JSON as the source for a <script> tag on your HTML page, it will automatically download the JSON and run it - creating a new data structure available to the code on your page:
</p>
<p>
	<code></p>
<pre><script type="text/javascript" src="http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=XXXX&#038;query=Cameron Adams&#038;ouput=json" /></pre>
<p>	</code>
</p>
<p>
	The search service returns XML by default, but by specifying &#8220;output=json&#8221;, the Yahoo! API method changes its output format and gives us a JSON string instead.
</p>
<p>
	<script> elements are not restricted by current domain security, so you are able to directly reference any address, anywhere on the Web. This can be done dynamically, when you need new data, by inserting new <script> elements into the DOM with appropriate CGI parameters for the query you&#8217;re constructing:
</p>
<p>
	<code></p>
<pre>var newScript = document.createElement("script");
		newScript.setAttribute(&#8221;src&#8221;, &#8220;http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=XXXX&#038;query=Cameron Adams&#038;ouput=json&#8221;;
		document.getElementsByTagName(&#8221;body&#8221;)[0].appendChild(newScript);</pre>
<p>	</code>
</p>
<p>
	As with asynchronous XMLHttpRequest calls because the communication with the server takes an indeterminate amount of time, we can&#8217;t be certain when the data is going to be returned, so we have to have some way of triggering a response once all of the data has made it back to the browser. Some APIs provide you with a callback mechanism, where you provide the name of a function as an argument to the API method and the JSON string will be returned as an argument of that callback function.
</p>
<p>
	For the Yahoo! web search request used before, we can add a &#8220;callback&#8221; parameter which triggers one of our custom functions:
</p>
<p>
	<code></p>
<pre>var newScript = document.createElement("script");
		newScript.setAttribute(&#8221;src&#8221;, &#8220;http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=XXX&#038;query=Cameron Adams&#038;ouput=json&#8221;&#038;<strong>callback=exampleFunction;</strong>
		document.getElementsByTagName(&#8221;body&#8221;)[0].appendChild(newScript);</pre>
<p>	</code>
</p>
<p>
	Now, the JSON string that&#8217;s returned from the Yahoo! server will be wrapped inside a function call for the callback function we specified:
</p>
<p>
	<code><br />
		exampleFunction({"rsp": ... });<br />
	</code>
</p>
<p>
	When the JavaScript &#8220;file&#8221; gets executed, the callback funciton will be automatically executed and passed the new JSON data as an argument.
</p>
<p>
	Yahoo! in particular is pushing JSON - internally as well as publicly - so quite a few of its Web APIs offer a JSON alternative to XML. It&#8217;s not guaranteed, however, that you&#8217;ll be able to get JSON data from any given Web API.
</p>
<h4>
	Go forth and API<br />
</h4>
<p>
The concepts behind Web APIs are fairly easy to grasp. You&#8217;re not coding anything that you haven&#8217;t coded before, it&#8217;s just data structures with a splash of XMLHttpRequest. The key sticking point is the architecture of the APIs themselves - getting data providers to give you access to their data, and then understanding the methods that those providers give you to query their data.
</p>
<p>
In this respect, documentation of an API is vitally important, and most of the Web APIs I included earlier do a good job of telling you what methods are available, how you can access them, and what you&#8217;re going to get in return. It&#8217;s then up to you to take that data and make something useful out of it.
</p>
<p class="diggit"><img src="http://www.digg.com/img/digg-guy-small.gif" alt="digg.com logo" /> Like this article? <a href="http://digg.com/programming/go_forth_and_API">Digg it</a>!</p>
<img src="http://thinkvitamin.com/?ak_action=api_record_view&id=1695&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://thinkvitamin.com/web-apps/go-forth-and-api/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
